Environment variables
Every variable the library reads, with ready-made setups for common providers.
Loading variables#
Copy what you need into a .env file. Load it before anything else — the library reads process.env but never loads the file itself.
import 'dotenv/config'; // first line of app.js — or run: node --env-file=.env app.js
Never commit .env. Commit a .env.example with the names and no secrets.
Every variable#
The library reads these from process.env. Each is optional unless you use its feature, and options passed in code always win.
| Variable | Used by | Default |
|---|---|---|
NODE_ENV | Errors | — · development adds stack to error responses |
AUTH_REFRESH_ENABLED | Auth | false |
AUTH_REFRESH_ROTATE | Auth | true |
AUTH_REFRESH_EXPIRES_IN | Auth | 30d |
SMTP_URL | Email sender | — |
SMTP_HOST · SMTP_PORT · SMTP_SECURE | Email sender | — · 587 · on for port 465 |
SMTP_USER · SMTP_PASS | Email sender | — |
MAIL_FROM | Email sender | required with SMTP |
APP_NAME | Email templates | empty |
REDIS_URL | Redis cache | — |
CACHE_TTL | Redis cache | 60 |
CACHE_PREFIX | Redis cache | cs: |
CACHE_ENABLED | Redis cache | on when cache is set · false turns caching off everywhere |
S3_ENDPOINT · S3_BUCKET_NAME | S3 upload | required |
S3_SPACES_KEY · S3_SPACES_SECRET | S3 upload | required |
S3_REGION | S3 upload | us-east-1 |
JWT_SECRET, MONGODB_URI and PORT are names your app chooses — the library never reads them directly.
A complete .env.example#
Every variable the library reads, plus the two your app needs.
# ── App ─────────────────────────────────────────────
PORT=3000
MONGODB_URI=mongodb://localhost:27017/app
# ── Auth ────────────────────────────────────────────
# 32+ characters: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
JWT_SECRET=
# ── Refresh tokens ──────────────────────────────────
AUTH_REFRESH_ENABLED=true
AUTH_REFRESH_ROTATE=true # true: new refresh token on every refresh
AUTH_REFRESH_EXPIRES_IN=30d
# ── Email sender ────────────────────────────────────
SMTP_URL=smtps://user:pass@smtp.example.com:465
MAIL_FROM="Acme <no-reply@acme.com>"
APP_NAME=Acme
# ── Redis cache ─────────────────────────────────────
REDIS_URL=redis://localhost:6379
CACHE_TTL=60
CACHE_PREFIX=cs:
CACHE_ENABLED=true
# ── S3 upload ───────────────────────────────────────
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_SPACES_KEY=
S3_SPACES_SECRET=
S3_BUCKET_NAME=
S3_REGION=us-east-1
Setup: CRUD only#
The smallest setup: just the database.
PORT=3000
MONGODB_URI=mongodb://localhost:27017/app
Setup: auth#
Sign-in with short access tokens and 30-day sessions. Set AUTH_REFRESH_ROTATE=false to keep the same refresh token until it expires.
JWT_SECRET=4f9c1e…64-hex-characters…
AUTH_REFRESH_ENABLED=true
AUTH_REFRESH_ROTATE=true
AUTH_REFRESH_EXPIRES_IN=30d
Setup: email#
Use SMTP_URL, or the separate SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS variables. Install nodemailer.
# Catches every mail locally — UI at http://localhost:8025
SMTP_HOST=localhost
SMTP_PORT=1025
SMTP_SECURE=false
MAIL_FROM="Acme Dev <dev@localhost>"
APP_NAME=Acme (dev)
# Needs 2-step verification and an App Password
SMTP_HOST=smtp.gmail.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=you@gmail.com
SMTP_PASS=your-16-char-app-password
MAIL_FROM="Acme <you@gmail.com>"
APP_NAME=Acme
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=apikey
SMTP_PASS=SG.your-api-key
MAIL_FROM="Acme <no-reply@acme.com>"
APP_NAME=Acme
SMTP_HOST=email-smtp.us-east-1.amazonaws.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=your-ses-smtp-username
SMTP_PASS=your-ses-smtp-password
MAIL_FROM="Acme <no-reply@acme.com>"
APP_NAME=Acme
SMTP_HOST=smtp.mailgun.org
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=postmaster@mg.acme.com
SMTP_PASS=your-mailgun-smtp-password
MAIL_FROM="Acme <no-reply@acme.com>"
APP_NAME=Acme
Setup: Redis#
Install ioredis (or redis), set REDIS_URL, and add cache: true to a router. Use rediss:// for TLS.
# brew install redis && redis-server — or: docker run -p 6379:6379 redis
REDIS_URL=redis://localhost:6379
CACHE_TTL=60
REDIS_URL=rediss://default:your-password@your-db.upstash.io:6379
CACHE_TTL=60
REDIS_URL=rediss://your-cluster.xxxxxx.use1.cache.amazonaws.com:6379
CACHE_TTL=60
REDIS_URL=redis://:your-password@redis.internal:6379/2
CACHE_TTL=60
Setup: S3#
Pick your storage provider.
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
S3_SPACES_KEY=AKIA…
S3_SPACES_SECRET=…
S3_BUCKET_NAME=acme-uploads
S3_REGION=us-east-1
S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
S3_SPACES_KEY=your-r2-access-key-id
S3_SPACES_SECRET=your-r2-secret-access-key
S3_BUCKET_NAME=acme-uploads
S3_REGION=auto
S3_ENDPOINT=https://nyc3.digitaloceanspaces.com
S3_SPACES_KEY=DO00…
S3_SPACES_SECRET=…
S3_BUCKET_NAME=acme-uploads
S3_REGION=us-east-1
# docker run -p 9000:9000 -p 9001:9001 minio/minio server /data --console-address :9001
S3_ENDPOINT=http://localhost:9000
S3_SPACES_KEY=minioadmin
S3_SPACES_SECRET=minioadmin
S3_BUCKET_NAME=dev-uploads
S3_REGION=us-east-1