NODE_ENV & Environments
NODE_ENV is a conventional environment variable that tells your app — and much of the ecosystem — which environment it's running in, almost always development, production, or test. It's not special to Node itself, but Express, React, many libraries, and npm all read it to switch behavior: enabling optimizations and disabling debug aids in production, and the reverse in development. Setting it correctly (especially to production in production) has real performance and security consequences. This page covers what NODE_ENV controls, the three standard values, the costly mistake of not setting it to production, and how to branch on it sensibly.
What NODE_ENV is — and the three standard values
| Used for | Typical behavior |
|---|---|---|
| Local coding | Verbose errors, stack traces, hot reload, no caching |
| Live deployment | Optimizations on, debug info off, caching, minimal errors |
| Running the test suite | Test database, deterministic settings, quiet logs |
# Set it in the environment where the app runs: NODE_ENV=production node app.js # or via your platform's config (Docker, systemd, Kubernetes, PaaS dashboard)
The costly mistake — forgetting production
// Express, for example, changes behavior based on NODE_ENV:
// • production → caches view templates, terse error pages (no stack traces to clients)
// • not set → no view caching, FULL stack traces leaked in error responses
// A quick check at startup to catch the mistake:
if (process.env.NODE_ENV !== 'production') {
console.warn('⚠ NODE_ENV is not "production" — running in slow/unsafe mode')
}Branching on the environment
const isProd = process.env.NODE_ENV === 'production'
const isTest = process.env.NODE_ENV === 'test'
// Use it to choose environment-appropriate behavior:
const logger = isProd
? pino({ level: 'info' }) // structured JSON, info level
: pino({ transport: { target: 'pino-pretty' }, level: 'debug' }) // pretty, verbose
app.use(isProd ? compression() : ((req, res, next) => next())) // compress only in prod
if (!isProd) {
app.use(errorHandlerWithStackTraces) // detailed errors OFF in production
}