Overview
OmniEHR uses environment variables for configuration across server and client applications. This page documents all available variables, their purposes, and validation rules.Server Environment Variables
Server environment variables are defined inserver/.env and loaded via the dotenv package.
Required Variables
These variables must be set or the server will fail to start with an error message.The server validates required environment variables on startup in
server/src/config/env.js.NODE_ENV
Application environment mode
development- Local development with verbose loggingproduction- Production deployment with optimized settingstest- Testing environment
- Controls logging verbosity
- Affects error message detail in API responses
- Used by Express for optimizations
PORT
Port number for the API server to listen on
4000
Example:
- Must be a valid port number (1-65535)
- Ensure the port is not already in use
- In production, consider using standard ports (80/443) with reverse proxy
MONGODB_URI
MongoDB connection string
mongodb://[username:password@]host[:port]/database[?options]
Examples:
- Used by Mongoose to connect to MongoDB
- Connection happens in
server/src/config/db.js - For production, use authentication and TLS
- Set
strictQuery: truefor schema validation
JWT_SECRET
Secret key for signing and verifying JWT access tokens
- Long random string (minimum 32 characters recommended)
- High entropy for security
- Must remain constant across server restarts
- Used by
jsonwebtokenlibrary inserver/src/utils/jwt.js - Changing this will invalidate all existing tokens
- Store securely in production (AWS Secrets Manager, HashiCorp Vault, etc.)
- Never expose in client-side code or logs
JWT_EXPIRES_IN
Token expiration time for JWT access tokens
60- 60 milliseconds2m- 2 minutes8h- 8 hours (recommended for development)1d- 1 day7d- 7 days
- Shorter expiration = better security, more frequent re-authentication
- Longer expiration = better UX, higher risk if token is compromised
- For production, consider 15-60 minutes with refresh token rotation
- Balance security requirements with user experience
PHI_ENCRYPTION_KEY
256-bit AES encryption key for protecting PHI (Protected Health Information)
- Exactly 64 hexadecimal characters (32 bytes)
- Used for AES-256-GCM encryption
- Must remain constant or encrypted data becomes unrecoverable
- Patient name (givenName, familyName)
- Contact information (phone, email)
- Address (line1, city, state, postalCode)
- Algorithm: AES-256-GCM (Galois/Counter Mode)
- Implementation:
server/src/services/cryptoService.js - Each field stores:
{ iv, authTag, content }for authenticated encryption - Random IV per encryption operation
server/src/services/cryptoService.js
Optional Variables
CORS_ORIGIN
Allowed origin for CORS requests
http://localhost:5173
Examples:
server/src/app.js
- Set to your frontend URL to allow API requests
- Must include protocol (
http://orhttps://) - For production, use exact domain (no wildcards for credentialed requests)
- Credentials are enabled for cookie-based authentication
Client Environment Variables
Client environment variables are defined inclient/.env and embedded into the build by Vite.
Vite only exposes environment variables prefixed with
VITE_ to the client bundle. This prevents accidentally exposing secrets.VITE_API_BASE_URL
Base URL for API requests from the frontend
{protocol}://{host}:{port}/api
Examples:
- Must end with
/apito match server route prefix - Include protocol and port for local development
- Use HTTPS in production
- Changes require rebuild (
npm run build)
client/src/api/client.js
Environment Variable Loading
Server
The server uses thedotenv package to load variables:
server/src/config/env.js
- Validates all required variables on startup
- Provides type conversion (e.g., PORT to number)
- Exports a clean config object for use throughout the app
- Fails fast if configuration is invalid
Client
Vite automatically loads.env files and exposes VITE_* variables:
.env.[mode].local(e.g.,.env.production.local).env.[mode](e.g.,.env.production).env.local.env
Security Best Practices
Never Commit Secrets
Add to.gitignore:
.env.example files with dummy values.
Use Secrets Management in Production
AWS Secrets Manager
Store and rotate secrets automatically
HashiCorp Vault
Centralized secrets and encryption
Environment Variables
Use platform-provided env vars (Heroku, Vercel, etc.)
Encrypted Files
Encrypt .env files with SOPS or git-crypt
Rotate Secrets Regularly
Validate Input
OmniEHR validates all environment variables on startup. Never skip validation in production.
Example Configuration Files
Development
Production
Troubleshooting
”Missing required environment variable”
Cause: A required variable is not set inserver/.env
Solution:
- Check that
server/.envexists - Verify all required variables are present
- Ensure no typos in variable names
- Restart the server after changes
”PHI_ENCRYPTION_KEY must be a 64-char hex string”
Cause: The encryption key is invalid Solution:- Generate new key:
openssl rand -hex 32 - Copy exactly 64 hex characters
- No spaces, quotes, or line breaks
- Paste into
server/.env
Client can’t reach API
Cause:VITE_API_BASE_URL is incorrect
Solution:
- Verify API server is running
- Check
VITE_API_BASE_URLmatches server URL - Include
/apisuffix - Rebuild client:
npm run build --workspace client - Check CORS_ORIGIN on server matches client origin
Environment variables not updating
Server: Restart the dev server (Ctrl+C then npm run dev)
Client: Vite requires restart and rebuild for env var changes
Next Steps
Local Setup
Complete local development setup guide
Production Deployment
Deploy to production with security hardening
Security Architecture
Learn about HIPAA-aligned security controls
Database Configuration
MongoDB setup and encryption