Home/Blog/Environment Variables & Secrets Management: Doing It Right in Node.js
Software Development
Environment Variables & Secrets Management: Doing It Right in Node.js
AJAjish StephenAugust 8, 20267 min read
Almost every leaked API key or database password I've seen traced back to the same root cause: a secret that was never really treated as a secret. Here's how to actually handle environment variables and secrets in a Node.js project, from local development through to production.
Start with .gitignore, not after the first commit
Before anything else touches the project, make sure the real .env file can never be committed:
# .gitignore .env .env.local .env.*.local
Commit a .env.example instead, with the same variable names but placeholder values — this documents what's required without exposing anything real.
Validate required variables at startup, don't discover missing ones at runtime
A missing environment variable should fail loudly and immediately, not silently return undefined and cause a confusing bug three requests later:
// config.js — validate everything up front require('dotenv').config();
This throws immediately on app startup if anything required is missing, instead of the app booting fine and only failing when a specific route is hit hours or days later.
Type-safe validation with Zod (optional but worth it)
For a larger project, a schema library catches type mistakes too, not just missing values:
constenv= envSchema.parse(process.env);// throws a detailed error if anything is invalid
When to move beyond a plain .env file
→Once secrets need to be shared across multiple servers or team members, a plain file gets hard to manage and audit consistently
→A proper secrets manager (AWS Secrets Manager, HashiCorp Vault, or your cloud provider's equivalent) adds rotation, access logging, and fine-grained permissions a file on disk can't provide
→CI/CD secrets (like the GitHub Actions example from an earlier post) should live in the platform's own secrets store, never checked into the workflow file itself
If a secret does leak
Removing a committed secret from the latest commit is not enough — it's still recoverable from git history. Treat any leaked secret as immediately compromised: rotate it right away, rather than assuming a history rewrite fully contains the exposure, especially if the repository has ever been cloned or forked elsewhere.
Building a Node.js system that needs proper secrets and configuration management from day one? This is part of what I cover in DevOps services engagements.
Common questions
Is a .env file safe to use in production?
It is workable for a small deployment as long as it is never committed to version control and file permissions restrict who can read it. For larger deployments, a dedicated secrets manager provides better audit logging and rotation.
What is the most common way secrets accidentally leak in Node.js projects?
Committing a real .env file to git, or pasting a secret directly into code during debugging and never removing it. Both are preventable with a proper .gitignore from day one.
Should I validate environment variables at application startup?
Yes. Failing fast with a clear error when a required variable is missing is far better than the application failing unpredictably later, deep inside a request handler.
What happens if a secret is accidentally committed to git history?
It remains recoverable from git history indefinitely unless the history itself is rewritten. The safest response is to treat the secret as compromised and rotate it immediately.
Need your secrets and config managed properly?
I set up secure configuration and secrets management for real production systems.