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.envis a plain object exposing the process's environment variables — set by the shell, a.envloader, 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.envis always a string, even if something elsewhere assigns it a number —process.env.NUM = 42reads back as the string"42",typeofconfirmed as"string", not the number42. Comparisons likeprocess.env.PORT === 3000are always false;Number(process.env.PORT)orparseIntis 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 forundefinedat startup rather than trusting a value silently exists. - Since Node 20.6, the native
--env-fileCLI flag can load a.envfile straight intoprocess.envwith no external package required — covered in full, with its own verified execution, in the dedicated--env-filequestion;dotenvremains 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
.envfile 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
.envfile 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.