What is NODE_ENV
?
The NODE_ENV
environment variable became popular early in Node.js development as a convention to distinguish between runtime environments like development, testing, and production. It is now widely used and supported across many tools and frameworks in the Node.js ecosystem, allowing developers to implement environment-specific configurations and optimizations.
Unfortunatley, many developers don’t grasp its purpose and use it incorrectly.
Countless projects incorrectly use the environment variable NODE_ENV
to specify the name of their environment (like dev
, stg
, prd
, etc.) but the purpose of NODE_ENV
is to specify the type of the environment, not its name.
The expected values of NODE_ENV
are development
, test
and production
.
Various tools and libraries change their behaviour based on the value of NODE_ENV
:
- when
NODE_ENV
is set todevelopment
, some tools may load additional code to show useful warnings, enable hot reloading and skip optimizations that are not necessary when you are developing the app; - when
NODE_ENV
is set totest
, you may want to instrument your code for code coverage; - when
NODE_ENV
is set toproduction
, certain tools may optimize code execution paths, eliminate unused code, and apply optimizations as needed to enhance performance.
How some popular Node applications and framworks handle NODE_ENV
Node.js recommends to always set
NODE_ENV
toproduction
; setting it to a different value and using the value ofNODE_ENV
to drive the application behaviour is considered an anti-pattern:Various commands of Npm (
install
,update
,prune
,ci
, etc. ) use the value ofNODE_ENV
to include or exclude the dev dependencies from processing:Yarn v1 uses it on
yarn install
to include or exclude the dev dependencies:It seems that Yarn v2+ does not use the
NODE_ENV
environment variable and drives its behaviour based only on the command line arguments.Next.js recommends to use only one of
development
,test
orproduction
as the value ofNODE_ENV
. A different value might cause dependencies to work unexpectedly.Jest sets
NODE_ENV
totest
if it is not already set. Apparently, it does this so that the tested code can enable/disable logging, optimisations etc. when it runs in test mode. Jest itself does not change its behaviour based on the value ofNODE_ENV
.Setting
NODE_ENV
toproduction
makes Express:- cache view templates;
- cache CSS files generated from CSS extensions;
- generate less verbose error messages.
Source: https://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production
React uses the terms development build and production build everywhere in its documentation. These are the differences between them:
development build:
- includes helpful warnings, error messages, and debugging tools such as source maps;
- slower performance due to additional checks and verbose logging;
- used during the development phase to aid debugging and testing.
production build:
- minified and optimized for performance by removing warnings and unnecessary code;
- smaller file sizes, leading to faster load times and reduced bandwidth usage;
- intended for deployment to end users.
Although not officially documented, the two build modes are identified by checking the value of
NODE_ENV
againstproduction
ordevelopment
.
How to use NODE_ENV
in applications?
The applications should not know in what environment they run. The environment variables should be used to set the configuration values that vary across environments. When behaviour needs to differ across environments, the best way is to use the Strategy design pattern; implement the behaviour that varies in several components that implement the same interface and decide at runtime which of them to use based on the value of a configuration entry (provided as an environment variable). Use different values for the variable based on the environment (or environment type) where the application runs.
As an exception to the rule above, use the value of NODE_ENV
in applications to implement optimisations (or skip some costly verifications) when the code run in production and provide better support for developers (in the development mode.)