Skip to solution
mediumLow-Level Design

How do you manage configuration in a Node.js application for different environments?

1.1k views
01

Understand the problem

Question presented to candidate: "The same codebase needs a local database URL in development and a completely different one in production. How should that difference be represented in the code, and where should it be decided?"

What a strong answer should cover:

  • The standard mechanism is process.env.NODE_ENV (or an equivalent custom variable) selecting between environment-specific configuration values — the code itself stays identical across environments; only the values it reads differ, sourced from the actual deployment environment.
  • 📌 A concrete, verifiable pattern: a config-selection script correctly chose the development config by default (when NODE_ENV is unset), correctly switched to production when set, and threw a clear, immediate error for an unrecognized value rather than silently proceeding with undefined configuration — failing loudly at startup is the correct behavior for a genuinely unrecognized environment name.
  • Configuration should be validated once, at startup (covered in more depth in the dedicated environment-variables question) — checking every required value is present and correctly typed before the app starts serving any traffic, rather than discovering a missing value deep inside request handling.
  • Secrets (database passwords, API keys) should never be hardcoded per-environment in a config file committed to version control — they belong in actual environment variables (injected by the deployment platform, a secrets manager, or a .env file that is itself never committed), while non-secret structural configuration (feature flags, timeouts, non-sensitive URLs) can reasonably live in a committed config file.
  • A precise answer distinguishes configuration (values that differ by environment but are not secret) from secrets (values that must never appear in source control regardless of environment) — treating both identically is a common, real security mistake.
  • NODE_ENV=production also has real, automatic side effects in some frameworks/libraries beyond just an application's own config-switching logic (e.g. Express's own performance-related behavior differences) — worth knowing rather than assuming NODE_ENV is purely an application-level convention with zero built-in framework consequences.

Clarifying questions expected:

  • "Is the concern non-secret configuration differences, or actual secrets management?" — these deserve genuinely different handling.
  • "Does the deployment platform already inject environment-specific values, or does the app need to load them itself?" — decides how much of a custom loading mechanism is actually needed.

Code / implementation expected: Yes — the config-selection-by-NODE_ENV pattern, including the fail-loudly-on-unrecognized-value behavior, is the concrete, convincing part of the answer.

configurationenvironment variablesdeploymentbest practices
02

Attempt it yourself

Sketch your approach before reading the solution — that's what interviews test.

Nudge consolestandby

Stuck? Beam a request up — the console returns a conceptual nudge that guides your logic without spoiling the implementation.

03

Study the solution

Target Audience: Engineers preparing for Node.js interviews — assumes basic process.env familiarity. Difficulty: Medium

How to read this doc: Concepts are explained in plain language first, then tagged with 📌 Interview term:. The config-switching behavior below was actually run across

Solution ready — 2 min read

Classified // press E to declassify

04

Read the code

NODE_ENV-driven config selection, verified across development, production, and an unrecognized value
// config.js
const configs = {
  development: { dbHost: "localhost", logLevel: "debug" },
  production: { dbHost: "prod-db.internal", logLevel: "error" },
};

const env = process.env.NODE_ENV || "development";
const config = configs[env];
if (!config) {
  throw new Error(`No config for NODE_ENV=${env}`); // fail loudly, immediately, at startup
}

module.exports = config;

// $ node -e "console.log(require('./config'))"
// { dbHost: 'localhost', logLevel: 'debug' }
//
// $ NODE_ENV=production node -e "console.log(require('./config'))"
// { dbHost: 'prod-db.internal', logLevel: 'error' }
//
// $ NODE_ENV=staging node -e "console.log(require('./config'))"
// Error: No config for NODE_ENV=staging   <- fails immediately, not silently
05

Join the discussion

Discussion (0)

Sign in to join the discussion.

No responses yet. Be the first to share what you think.

Transmission complete // awaiting log

KEEP THE
STREAK ALIVE.

Dossier 44 of 152 decoded in the Node.js track. One more won't hurt.

Back to track