Docento.app
Notebook, coffee, and laptop on a desk
All Posts

.env Files for Development, Staging and Production: Naming and Precedence

By The Docento.app TeamPublished 4 min read
Try Docento's free PDF editor — No sign-up, 100% private — sign, annotate, and stamp PDFs in your browser.Open the editor

One .env file is fine for one machine. Real projects run in several places: a developer laptop, a test server, staging and production. Each needs different settings, and frameworks have conventions for handling that. The conventions vary, so know your tool's rules.

The environments

  • Development: your machine, with local databases and debug settings.
  • Test: automated tests, ideally isolated from real services.
  • Staging: a production-like environment for final checks.
  • Production: the live system, with real credentials and strict settings.

The goal is that the same code runs everywhere and only the configuration differs.

Common file names

File Typical purpose Committed?
.env Defaults shared by all environments Sometimes, if it holds no secrets
.env.local Your machine's overrides and secrets No
.env.development Settings for development mode Often, without secrets
.env.production Settings for production builds Often, without secrets
.env.test Settings for tests Often
.env.example Template listing required keys Yes

These names come from conventions popularised by frameworks, not from a standard. Whether a given file is loaded at all depends on the tool.

Example: Next.js and Vite style precedence

Frameworks such as Next.js load several files and apply a priority order. As a general pattern in these tools, real environment variables win first, then mode-specific local files such as .env.development.local, then .env.local (not loaded in test mode), then mode-specific files such as .env.development, then .env. Vite follows a very similar scheme with .env, .env.local, .env.[mode] and .env.[mode].local. Check the documentation for the exact order in your version.

Some frameworks also restrict which variables reach the browser. A prefix such as NEXT_PUBLIC_ or VITE_ marks variables that are bundled into client-side code, where anyone can read them. Never put a secret behind such a prefix.

Example: plain dotenv libraries

The basic dotenv library for Node.js loads one file, .env by default, and does not overwrite variables already set in the environment. You choose a different file by passing a path, so the environment-specific logic is yours to write. Python's python-dotenv works similarly, with an option to override existing variables.

Real environment variables come first

In the standard libraries, a variable already set in the process environment is not overwritten by the file. This is deliberate: on a production server, the platform's environment settings should win over any stray file. It also explains a common confusion: you edit .env, nothing changes, and the cause is a variable already exported in your shell.

Production: skip the file if you can

On hosted platforms, set variables through the platform's settings or secrets manager rather than shipping a .env file. Files are easy to leak, are copied around, and tend to drift. Containers should receive configuration at runtime, not have a file baked into the image.

A sensible layout

  1. Commit .env.example listing every key.
  2. Commit non-secret defaults in .env or .env.development if your framework uses them.
  3. Keep secrets in .env.local (ignored by git) on developer machines.
  4. Use the platform's secret store for staging and production.
  5. Document which variables are required, with allowed values.

Avoiding drift

  • Add a startup check that fails fast when a required variable is missing, instead of failing later in an obscure way.
  • Keep .env.example current in the same commit that adds a new variable.
  • Use a distinct credential per environment, so a leak in development does not expose production.

Checking the files

Syntax slips such as unclosed quotes or lines without = are easy to make across several files. Docento's Text & Markdown Editor checks .env and .env.* files in the browser and shows the failing line. For syntax rules see env file syntax, and for secrets handling see keeping .env files out of git.

Takeaway

Use a committed .env.example, framework-specific files for non-secret defaults, ignored local files for your secrets and the platform's secret store in production. Learn your framework's precedence rules, and remember real environment variables normally win.

Try Docento's free PDF editor

No sign-up, 100% private — sign, annotate, and stamp PDFs in your browser.

Open the editor

Related Posts