NODE_ENV Considered Harmful

Colin J. Ihrig

At some point in the distant past, certain Node.js projects adopted the convention of using the NODE_ENV environment variable to denote how the project was being run. For example:

# Testing. Perhaps while running unit tests.
NODE_ENV=test node index.js

# Development. Local or shared development environments.
NODE_ENV=dev node index.js
NODE_ENV=development node index.js

# Production environments.
NODE_ENV=prod node index.js
NODE_ENV=production node index.js

The previous example illustrates a few ways that I have seen NODE_ENV over the years. By itself, there is nothing wrong with this. In fact, it is helpful to have an easy way of determining this information.

The Problem

This pattern becomes problematic when code executes differently based on the value of NODE_ENV. Express is (curiously?) the most popular Node.js framework and one of the worst offenders. According to the Express Production best practices page, setting NODE_ENV=production alone can yield 3x performance improvements. The reason is that it enables better caching and other optimizations.

Performance improvements are great, except when you need to know that they exist and explicitly opt into them. This essentially means "operate in slow mode unless you are explicitly told to be fast."

I have personally encountered several Express projects running in production without NODE_ENV=production. At least one of these projects had been in production for years. That is a lot of performance left on the table for an extended period of time.

What to do?

If you are a Node.js user, set NODE_ENV=production everywhere and never think about it again.

If you are a Node.js library author, please stop using NODE_ENV in your code. If you insist on using it, make it default to production and let your users opt in to a slower development/debugging mode.