Configuration & dotenv

Read Env, Validate, Pass Around

Configuration & dotenv

Use @fastify/env to validate environment variables against a JSON Schema at boot, so missing configuration fails fast instead of crashing under load.

4 min read Level 2/5 #fastify#config#dotenv
What you'll learn
  • Register @fastify/env with a schema
  • Access values through app.config
  • Fail fast when required vars are missing

process.env works fine for a toy app, but production services need validation: required variables, correct types, defaults. @fastify/env plugs into Fastify’s schema system.

Install

npm i @fastify/env

Declare and Register

import fastifyEnv from '@fastify/env';

const schema = {
  type: 'object',
  required: ['DB_URL', 'JWT_SECRET'],
  properties: {
    PORT: { type: 'integer', default: 3000 },
    DB_URL: { type: 'string' },
    JWT_SECRET: { type: 'string', minLength: 32 },
    NODE_ENV: { type: 'string', enum: ['development', 'production', 'test'] },
  },
} as const;

await app.register(fastifyEnv, {
  schema,
  dotenv: true, // loads .env automatically
  confKey: 'config',
});

If JWT_SECRET is missing or shorter than 32 characters, register throws and the process exits before the server starts accepting traffic.

Read Values

app.get('/version', async () => ({
  port: app.config.PORT,
  env: app.config.NODE_ENV,
}));

await app.listen({ port: app.config.PORT });

app.config is typed when you use as const on the schema and a small declare module block in your TS types.

Layered Configuration

For multi-environment setups, load a base .env plus .env.production via the dotenv option’s path array. Anything not covered by env vars (feature flags, region metadata) is fetched in an onReady hook so the rest of the app can still depend on app.config.

TypeScript Setup →