Environment Variables

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

Written By Dev010

Last updated 2 months 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.