compareupdated 2026-04-17

dotenv vs config: which should you use in 2026?

An honest comparison of dotenv and config-based libraries (node-config, convict, zod-env). Trade-offs around validation, type safety, and schema enforcement.

TL;DR

  • Use dotenv for solo projects, prototypes, and small teams.
  • Use a config library (node-config, convict, zod-env, t3-env, envalid) the moment you have > 15 env vars, multiple deploy targets, or a type-safe codebase.
  • They're not mutually exclusive. Most teams use both: .env stays the source of values; a config library adds validation and types on top.

What dotenv does

dotenv does one thing — it parses .env and pushes keys into process.env. Nothing else. No validation, no types, no defaults, no schema. It's ~40 lines of real code, which is exactly why it's so widely adopted.

What config libraries add

Every config library layers some combination of:

  • Validation: required keys, allowed values, format checks.
  • Types: coerce "3000"3000, "true"true.
  • Defaults: fall back to a value when the variable is missing.
  • Schema: a single source of truth for what config exists.
  • Fail-fast: crash at startup instead of later, at runtime.

node-config

Hierarchical YAML/JSON files (default.yamldevelopment.yaml production.yaml) merged at boot. Overlays on top of env vars. Popular in older Node stacks. Heavier than zod-env for modern TypeScript.

convict

Mozilla-made. You define a schema with types, formats, and env-var mappings. Strong for multi-datacenter apps with deep config trees. Verbose compared to Zod-based libraries.

envalid

Minimal. envalid.cleanEnv(process.env, { PORT: envalid.port() }). Returns a typed object. Great if you already have dotenv and just want validation.

zod-env / t3-env

Modern TypeScript answer. You write a Zod schema, and you get a fully-typed env object. t3-env adds client/server separation for Next.js. These are the default choice for new TS projects.

Decision matrix

Concerndotenv onlydotenv + config lib
Tiny projectoverkill
TypeScript codebaseno types
> 15 env varspainful
Multi-env (dev/staging/prod)fine
Fail-fast validationno
Onboarding new devs.env.exampleschema
Serverless / edge✓ (zod-env)

Recommended stack (2026)

  1. Keep .env as the raw source of values.
  2. Commit .env.examplegenerate it from .env.
  3. Layer t3-env (or zod-env) for type-safety.
  4. Validate every new env var in CI by running the app with a stripped .env.

What to do now

If you're already on dotenv and the missing-key errors have started piling up, add a config library today — it's a one-hour migration. If you're starting fresh, go straight to t3-env on Next.js or zod-env elsewhere.

For everything that happens before parsing — catching syntax errors, duplicates, empty values — run your file through the validator. And for syncing across environments, the diff checker is faster than any CLI.

Related guides

Related tools