controller-sets v3.3.0

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.

VariableUsed byDefault
NODE_ENVErrors— · development adds stack to error responses
AUTH_REFRESH_ENABLEDAuthfalse
AUTH_REFRESH_ROTATEAuthtrue
AUTH_REFRESH_EXPIRES_INAuth30d
SMTP_URLEmail sender—
SMTP_HOST · SMTP_PORT · SMTP_SECUREEmail sender— · 587 · on for port 465
SMTP_USER · SMTP_PASSEmail sender—
MAIL_FROMEmail senderrequired with SMTP
APP_NAMEEmail templatesempty
REDIS_URLRedis cache—
CACHE_TTLRedis cache60
CACHE_PREFIXRedis cachecs:
CACHE_ENABLEDRedis cacheon when cache is set · false turns caching off everywhere
S3_ENDPOINT · S3_BUCKET_NAMES3 uploadrequired
S3_SPACES_KEY · S3_SPACES_SECRETS3 uploadrequired
S3_REGIONS3 uploadus-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
Esc
↑ ↓ to move↵ to open