Environment Variables

A complete reference for all environment variables used by CareNova, including required and optional configuration.

Written By Dev010

Last updated 19 days ago

CareNova uses environment variables to configure all external services, database connections, and application behavior.

This page is a complete reference for every variable used by the application.

Creating the Environment File

Inside the root of carenova-app/, create a new file named .env.local:

touch .env.local

The file must be placed at the project root:

carenova-app/
β”œβ”€β”€ app/
β”œβ”€β”€ components/
β”œβ”€β”€ lib/
β”œβ”€β”€ public/
β”œβ”€β”€ .env.local        ← create this file here
β”œβ”€β”€ package.json
└── next.config.js

.env.local is already included in .gitignore and will never be committed to version control. Never rename it to .env as that file can be accidentally committed.

Complete Variable Reference

Supabase β€” Authentication & Database

These variables connect CareNova to your Supabase project. Found in Supabase Dashboard β†’ Settings β†’ API.


NEXT_PUBLIC_SUPABASE_URLRequired Β· Public

Your Supabase project URL. Used by both the frontend and backend to communicate with Supabase services.

NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co

Where to find it: Settings β†’ API β†’ Project URL


NEXT_PUBLIC_SUPABASE_ANON_KEYRequired Β· Public

The public anonymous API key. Used for authentication and client-side Supabase requests. Safe to expose in the browser β€” Supabase enforces security at the database level.

NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

Where to find it: Settings β†’ API β†’ Project API Keys β†’ anon public


SUPABASE_SERVICE_ROLE_KEYRequired Β· Server only

The service role key. Used for admin operations, storage bucket management, and seed scripts. Bypasses Row Level Security β€” never expose this publicly.

SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Where to find it: Settings β†’ API β†’ Project API Keys β†’ service_role

This key has full database access. Keep it server-side only and never commit it to a public repository.


Database β€” Drizzle ORM Connection

DATABASE_URLRequired Β· Server only

The PostgreSQL connection string used by Drizzle ORM for all database queries. Must use the Transaction pooler on port 6543 with ?pgbouncer=true appended.

DATABASE_URL=postgresql://postgres.[ref]:[YOUR-PASSWORD]@aws-0-[region].pooler.supabase.com:6543/postgres?pgbouncer=true

Where to find it: Settings β†’ Database β†’ Connection String β†’ Transaction mode

⚠️ Port 6543 and ?pgbouncer=true are both required. Using port 5432 without pgBouncer will cause connection failures under load. CareNova uses prepare: false in Drizzle config for pgBouncer transaction mode compatibility.


DIRECT_DATABASE_URLOptional Β· Server only

A direct session-mode connection string used only when running npm run db:migrate. Not required for normal development or production operation.

DIRECT_DATABASE_URL=postgresql://postgres.[ref]:[YOUR-PASSWORD]@aws-0-[region].pooler.supabase.com:5432/postgres

Where to find it: Settings β†’ Database β†’ Connection String β†’ Session mode


Application Configuration

NEXT_PUBLIC_SITE_URLRequired Β· Public

The base URL of your application. Used for authentication redirects and email confirmation links.

# Local development
NEXT_PUBLIC_SITE_URL=http://localhost:3000

# Production
NEXT_PUBLIC_SITE_URL=https://yourdomain.com

This value must match the Site URL configured in Supabase β†’ Authentication β†’ URL Configuration. If they do not match, email confirmation links will not work.


CRON_SECRETRequired Β· Server only

A secret string that protects the cleanup cron endpoint at /api/cron/cleanup-auth. Any request to this endpoint without the correct secret returns a 401 error.

CRON_SECRET=your-random-secret-string

Generate a secure value using:

openssl rand -base64 32

CARENOVA_DEBUGOptional Β· Server only

Enables verbose [CareNova] debug logs in the terminal. Useful for tracing auth flows, DB queries, and layout performance during development.

# Enable debug logs
CARENOVA_DEBUG=1

# Disable (default)
# CARENOVA_DEBUG=0

Set to 1 for local development only. Remove or set to 0 for production β€” leaving it enabled in production will output excessive logs.

When enabled, the following are activated:

  • Verbose auth and layout trace logs

  • Drizzle SQL query logger (prints every query)

  • Extra dashboard performance timing

  • Background task failure warnings


Email β€” Resend

RESEND_API_KEYRequired for email Β· Server only

API key for sending transactional emails via Resend β€” signup confirmation, password reset, and email verification.

RESEND_API_KEY=re_xxxxxxxxxx

Where to find it: resend.com β†’ API Keys β†’ Create API Key

Without this key, email confirmation will not work in production. During local development, a mock log is shown in the terminal instead of sending a real email.


Envato License

ENVATO_PERSONAL_TOKENRequired for production Β· Server only

Your Envato personal token. Used to verify Envato purchase codes submitted on the /setup activation screen.

ENVATO_PERSONAL_TOKEN=your-envato-personal-token

Where to find it: build.envato.com/api/ β†’ Create a new token with Purchase permission


ENVATO_ITEM_IDRequired for production Β· Server only

The CodeCanyon item ID for CareNova. Used to verify that a submitted purchase code belongs to CareNova and not another product.

ENVATO_ITEM_ID=your-codecanyon-item-id

Where to find it: Your CodeCanyon listing URL β€” the number at the end is your item ID.


Demo Data

DEMO_PASSWORDOptional Β· Server only

The password assigned to all demo accounts created by npm run db:seed. If not set, defaults to Demo123!.

DEMO_PASSWORD=Demo123!

Demo accounts created by the seed script:

  • admin@carenova.demo

  • doctor@carenova.demo

  • receptionist@carenova.demo

  • nurse@carenova.demo

Change this value before seeding if you want custom demo account passwords. The value must meet the password policy β€” minimum 8 characters, uppercase, lowercase, number, and special character.


Optional Configuration

DIRECT_DATABASE_URLOptional Β· Server only

Already covered in the Database section above. Only needed for npm run db:migrate.


TEETH_IMAGES_BASE_URLOptional Β· Server only

Base URL for teeth images used in the Odontogram module. If not set, a default external URL is used.

TEETH_IMAGES_BASE_URL=https://your-domain.com/teeth

Only required if you want to self-host the odontogram tooth images.


Complete .env.local Template

Copy this template into your .env.local file and replace all placeholder values:

# ─── Supabase (Auth + Database) ─────────────────────────────
# Get these from: Supabase Dashboard β†’ Settings β†’ API
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

# ─── Database (Drizzle ORM) ──────────────────────────────────
# Use Transaction pooler (port 6543) β€” add ?pgbouncer=true
# Get from: Settings β†’ Database β†’ Connection String β†’ Transaction mode
DATABASE_URL=postgresql://postgres.[ref]:[PASSWORD]@aws-0-[region].pooler.supabase.com:6543/postgres?pgbouncer=true

# Optional: Session mode (port 5432) for migrations only
# Get from: Settings β†’ Database β†’ Connection String β†’ Session mode
# DIRECT_DATABASE_URL=postgresql://postgres.[ref]:[PASSWORD]@aws-0-[region].pooler.supabase.com:5432/postgres

# ─── Supabase Service Role ───────────────────────────────────
# Required for storage and admin operations β€” never expose publicly
# Get from: Settings β†’ API β†’ service_role key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# ─── Site URL ────────────────────────────────────────────────
# Must match Site URL in Supabase Auth β†’ URL Configuration
# Local: http://localhost:3000 | Production: https://yourdomain.com
NEXT_PUBLIC_SITE_URL=http://localhost:3000

# ─── Resend (Transactional Email) ────────────────────────────
# Required for email confirmation and password reset
# Get from: https://resend.com/api-keys
RESEND_API_KEY=re_xxxxxxxxxx

# ─── Cron Job Protection ─────────────────────────────────────
# Protects /api/cron/cleanup-auth β€” generate with: openssl rand -base64 32
CRON_SECRET=your-random-secret-string

# ─── Envato License Verification ─────────────────────────────
# Required for purchase code activation on first launch
# Get from: https://build.envato.com/api/
ENVATO_PERSONAL_TOKEN=your-envato-personal-token
ENVATO_ITEM_ID=your-codecanyon-item-id

# ─── Demo Data (optional) ────────────────────────────────────
# Password for demo accounts created by npm run db:seed
# Default: Demo123! β€” must meet password policy requirements
# DEMO_PASSWORD=Demo123!

# ─── Debug Logs (development only) ──────────────────────────
# Set to 1 to enable verbose [CareNova] logs β€” remove for production
# CARENOVA_DEBUG=1

# ─── Teeth Images (optional) ─────────────────────────────────
# Base URL for odontogram tooth images β€” uses default if not set
# TEETH_IMAGES_BASE_URL=https://your-domain.com/teeth

Variable Summary Table

Variable

Required

Visibility

Used For

NEXT_PUBLIC_SUPABASE_URL

βœ… Yes

Public

Supabase connection

NEXT_PUBLIC_SUPABASE_ANON_KEY

βœ… Yes

Public

Supabase auth

SUPABASE_SERVICE_ROLE_KEY

βœ… Yes

Server only

Admin operations, storage

DATABASE_URL

βœ… Yes

Server only

All DB queries (port 6543)

NEXT_PUBLIC_SITE_URL

βœ… Yes

Public

Auth redirects

RESEND_API_KEY

βœ… Yes

Server only

Email sending

CRON_SECRET

βœ… Yes

Server only

Cron endpoint protection

ENVATO_PERSONAL_TOKEN

βœ… Production

Server only

License verification

ENVATO_ITEM_ID

βœ… Production

Server only

License verification

DIRECT_DATABASE_URL

⬜ Optional

Server only

Migrations only (port 5432)

DEMO_PASSWORD

⬜ Optional

Server only

Seed script demo accounts

CARENOVA_DEBUG

⬜ Optional

Server only

Verbose debug logging

TEETH_IMAGES_BASE_URL

⬜ Optional

Server only

Odontogram images

Security Best Practices

  • Never commit .env.local to any repository β€” it is already in .gitignore

  • Never expose SUPABASE_SERVICE_ROLE_KEY in client-side code or browser-accessible files

  • Use strong values for CRON_SECRET β€” generate with openssl rand -base64 32

  • Use different values for development and production environments

  • Store production secrets in your hosting platform's environment variable settings β€” never in files

Setting Variables in Production (Vercel)

For production deployments on Vercel:

  1. Go to your Vercel project dashboard

  2. Navigate to Settings β†’ Environment Variables

  3. Add each variable with its production value

  4. Set the environment scope β€” Production, Preview, or Development

  5. Redeploy your application after adding variables

NEXT_PUBLIC_SITE_URL must be set to your actual production domain in Vercel β€” for example https://app.yourdomain.com. The localhost value from .env.local must not be used in production.

Helpful resources:

Next Step

Environment variables are now configured. Continue to the Deployment guide to take CareNova to production, or return to the Installation Guide to complete your local setup.