Skip to main content

Configuration system

One typed ConfigType per environment. process.env is read exactly once, in the matching configuration module — nowhere else in the codebase.

How it works

Docker Compose injects .env.development at the container boundary. The backend reads NODE_ENV, loads the matching configuration module, and assembles a single ConfigType object that’s passed everywhere.

Configuration modules

FileWhen loaded
apps/backend/src/configuration/development.tsLocal Docker dev (NODE_ENV=development)
apps/backend/src/configuration/staging.tsRailway staging environment
apps/backend/src/configuration/production.tsRailway production environment
apps/backend/src/configuration/test.tsJest test suite (NODE_ENV=test)
Each module exports a plain object matching ConfigType. Tool choices are set here — for example, test.ts sets paymentProcessor.client to stripeMock so tests never hit the real Stripe API.

What ConfigType covers

ConfigType is the single source of truth for all app config. Key sections:
SectionWhat it configures
serverPort, session secret, cookie domain, CORS origins
databasePostgres connection (host, port, user, password, dbname)
redisRedis connection URL
tools.queueQueue adapter type + adapter-specific config (BullMQ / SQS)
tools.loggerLogger adapter type (Pino / Console)
tools.metricsMetrics adapter type + host/port (StatsD)
tools.mailerMailer adapter type + API key (SendGrid / Local)
tools.analyticsAnalytics adapter type + API key (Amplitude / Local)
tools.paymentProcessorPayment processor type + Stripe keys (Stripe / StripeMock)
deploymentRailway project/service IDs + deploy strategy

Changing which tool implementation you use

When you swap a tool adapter, three things must change together:
  1. apps/backend/package.json — add/remove the tooling-* workspace dependency.
  2. apps/backend/src/configuration/<env>.ts — update the client discriminator and any adapter-specific fields.
  3. Environment variables — add/remove the env vars the new adapter reads.
Then run make pnpm-install to update the lockfile, and make test module=backend to verify.
📖 See also: Configuration (Getting Started) for a step-by-step walkthrough with examples for every adapter.

What’s next?