Using NODE_ENV with multiple environments in JavaScript projects
Solution 1
NODE_ENV
is used to differentiate between development and production instances. It is not a good idea to run production code without NODE_ENV=production
. NODE_ENV=development
is usually not that important, because libraries usually just check to see if NODE_ENV !== 'production'
. So if you want to have multiple production node environments, or production-like environments, each of them should set NODE_ENV=production
. That said, you can definitely set other environment variables to whatever values you desire, and read them back from node at runtime.
A reasonable example would be to have a local
staging
and production
versions of your configuration. In this case, I would recommend having NODE_ENV
be just one of the parameters you set up for each environment. For instance, you might want three different databases for each of local
, staging
and production
but set NODE_ENV
to development
on local
, and production
for both staging
and production
.
Since the variables will be shell variables, you will need a way of loading certain environment variables on the target operating system prior to running the server. Modules like https://www.npmjs.com/package/dotenv look promising for this purpose.
Solution 2
NODE_ENV
should be set to either development
or production
in traditional sense.
The reason being, when you're building a front-end application (React, etc), you either build the application in development
mode or production
mode. For example, in development
mode, you will watch for changes and build continuously. In production mode, you minify the code and optimize it for size.
In case of a node server, the NODE_ENV
refers to what mode you start your application with. For example, in development
mode, you configure your server and install all devDependencies
and watch for changes and live reload the server. And in production
mode, you only install dependencies
and start the server with optimized configuration.
Now talking about different production environments, say staging
, pre-live
, live
, etc, you should use a separate ENV variable for this. Except local
, all other environments are considered production
environments and your app should be built with and start in production
mode in these environments.
You usually load different configurations, say api keys, urls for each environment. These should be differentiated with a separate ENV variable like APP_ENV
.
I usually use APP_ENV
to differentiate between staging
and live
environments.
This is how the package.json
will look like with different start scripts for different environments
"scripts": {
"start:local": "NODE_ENV=development APP_ENV=local your-start-script",
"start:staging": "NODE_ENV=production APP_ENV=staging your-start-script",
"start:live": "NODE_ENV=production APP_ENV=live your-start-script",
}
You will need to start the app with the right start script in each environment.
seansean11
Front-end developer and UI designer that enjoys many of the fine things on the tierra madre.
Updated on June 15, 2022Comments
-
seansean11 almost 2 years
I work on many projects that run on Express servers, whether they are front-end (i.e. React.js) codebases or server-side
Node.js
codebases
.Many times with the front-end
codebases
I would load conditional configuration based onNODE_ENV
, such as the URL of the restful API that the front-end makes requests to.I many times also used NODE_ENV to conditionally load things like DB configuration for server-side
Node.js
projects.On a project that consisted of development, staging, and production (3 environments), I would usually set up my code to load configuration based on the
NODE_ENV
being set to any one of those 3 environments (and maybe also "local").I was recently working on a project that was referring to the production environment as "live."
When I decided to set the NODE_ENV=live for this environment, a coworker pointed out a major flaw with this approach.
It seems that Express and some other libraries for Node.js latch onto the fact that you will either be using "production" or "development" as your
NODE_ENV
and using other names for your environments can have unexpected effects.For example, Express needs
NODE_ENV=production
in order to run in "production" mode. According to the Express docs "Tests indicate that just doing this can improve app performance by a factor of three!"Basically, I'm curious if it is considered common practice to set the
NODE_ENV
to values other than "development" and "production," like I've been doing in my projects.I feel that if I'm going to deploy my code to the development or staging environments on the cloud, I don't think they should run in a different Express "mode" than the production environment.
Does it make more sense to maintain configurations separate from
NODE_ENV
?For example, does it make sense to base your configuration off of a variable like
APP_ENV
, while ensuring thatNODE_ENV
is either "development" or "production" forframeworks/packages
like Express. -
seansean11 about 7 yearsIt seems you are suggesting that NODE_ENV should stick to either "development" or "production" and configuration can be loaded another way (i.e. adding a unique dotenv file to each of your project environments). This makes sense, but I still feel like I see configuration based on NODE_ENV very often in the wild. Take Loopback for example, loopback.io/doc/en/lb2/…. They mention in the docs, that you can use NODE_ENV=staging and set up a config.staging.json file. I'm not saying this is correct, but it seems to be fairly prevalent.
-
Mobius about 7 yearsIt may exist in the wild, and it is probably effective for non-production environments, but because many libraries enable optimizations when
NODE_ENV
is set toproduction
, you should make certain that you have that set for production environments. -
Mobius about 7 years@seansean11 are you looking for a different kind of answer? As far as best practices go, it is extremely unwise to not use
NODE_ENV=production
for many packages. I don't know if you are using them or not, but it is an industry best practice. -
seansean11 about 7 yearsThe answer is great. I still can't believe that entire (popular) libraries are built around the idea that your config will load from the NODE_ENV github.com/lorenwest/node-config. I'm sure many people using libraries like this set their NODE_ENV to values other than
development
orproduction
, in order to accommodate environment specific configuration and don't realize the implications. -
Sharad S Katre over 2 yearsAbove scripts are not working in case of Windows System? Any solution for that?
-
Sandeep Parashar over 2 yearsI am curious to know that if I set
NODE_ENV=production
for actually non-production environments like QA, Stage, etc. where I have to run unit tests during CI/CD pipeline, will the unit test packages (Mocha, Jest, and Chai in my case) added as devdependencies will still be loaded in those environments?