Skip to the solution
EasyPhone Screen6 min read

How do you handle environment variables in Node.js?

49 views

The problem

Question presented to candidate: "Your app reads process.env.PORT and passes it straight to app.listen(). A teammate says this sometimes breaks in a subtle way. What is the bug, and how do you handle environment variables correctly?"

What a strong answer should cover:

  • process.env is a plain object exposing the process's environment variables β€” set by the shell, a .env loader, a container orchestrator, or the CI system β€” as the primary way Node.js applications receive runtime configuration (ports, secrets, feature flags, environment name).
  • πŸ“Œ The precise, verifiable gotcha: every value on process.env is always a string, even if something elsewhere assigns it a number β€” process.env.NUM = 42 reads back as the string "42", typeof confirmed as "string", not the number 42. Comparisons like process.env.PORT === 3000 are always false; Number(process.env.PORT) or parseInt is required first.
  • Reading a variable that was never set returns undefined (not an error, not an empty string) β€” this is why config-validation code typically checks explicitly for undefined at startup rather than trusting a value silently exists.
  • Since Node 20.6, the native --env-file CLI flag can load a .env file straight into process.env with no external package required β€” covered in full, with its own verified execution, in the dedicated --env-file question; dotenv remains relevant for interpolated values or multi-file layering that the native flag does not do.
  • Values should be validated at startup, not read ad hoc throughout the codebase β€” failing fast with a clear error for a missing required variable is far preferable to a confusing runtime failure deep inside request handling.
  • Secrets specifically should never be committed in a .env file checked into version control β€” a good answer distinguishes "environment variables as a mechanism" from "how the actual secret values get to that environment safely" (a secrets manager, CI-injected variables, etc.), which is a separate, larger operational concern.

Clarifying questions expected:

  • "Is this config that varies by environment (dev/staging/prod), or an actual secret?" β€” secrets warrant more careful handling than plain config.
  • "Does the deployment platform already inject environment variables (a container orchestrator, a PaaS), or does the app need to load a .env file itself?" β€” decides whether --env-file/dotenv is even relevant here.

Code / implementation expected: Yes β€” demonstrating the string-coercion gotcha directly, and a small startup-validation pattern, is the concrete, convincing part of the answer.

  • environment variables
  • configuration
  • security

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 9 sections

Read the code

JavaScriptThe string-coercion gotcha and a missing-variable startup-validation pattern, both actually run
process.env.NUM = 42;
console.log(typeof process.env.NUM, process.env.NUM);
// string 42   <- NOT the number 42

console.log(typeof process.env.MISSING_VAR);
// undefined   <- no throw

// Startup validation pattern:
const required = ["DATABASE_URL", "PORT"];
for (const key of required) {
  if (process.env[key] === undefined) {
    throw new Error(`Missing required environment variable: ${key}`);
  }
}
const port = Number(process.env.PORT); // parsed explicitly β€” comparing the raw string to a number is always false

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 35 of 152 in Node.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Node.js questions
Up nextMedium

How does the Node.js event loop work?

Continue