compareupdated

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.yaml → development.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 project✓overkill
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.example — generate 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.

FAQ

Does adding a config library mean I stop using dotenv?

No — they're layered, not swapped. dotenv still reads the .env file into process.env; the config library (zod-env, envalid, convict) then validates and types what dotenv loaded.

What if my project is JavaScript, not TypeScript?

zod-env and t3-env give the most value in TypeScript, since their whole point is compile-time types. For a plain JS project, envalid or convict give you the validation and fail-fast behaviour without requiring a type system.

Does schema validation slow down cold starts on serverless or edge functions?

Negligibly — validation runs once, at module import, not per-request. The bigger constraint on edge runtimes is that some config libraries (convict, node-config) assume Node APIs that aren't available at the edge; zod-env has no such dependency.

What actually changes in production when I add validation?

A missing required variable becomes a loud crash at boot instead of a silent undefined that surfaces later as a broken database call or a 500 in production traffic. That's the entire value proposition — you find the problem at deploy time, not from a user's bug report.

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