421

For use in express.js environments. Any suggestions?

Harikrishnan
  • 9,688
  • 11
  • 84
  • 127
Mark Nguyen
  • 7,168
  • 9
  • 31
  • 41

17 Answers17

839

Before running your app, you can do this in console,

export NODE_ENV=production

Or if you are in windows you could try this:

SET NODE_ENV=production

for PowerShell:

$env:NODE_ENV="production"

or you can run your app like this:

NODE_ENV=production node app.js

You can also set it in your js file:

process.env.NODE_ENV = 'production';

But I don't suggest to do it in your runtime file, since it's not easy to open up VIM in your server and change it to production. You can make a config.json file in your directory and everytime your app runs, it reads from it and sets the configuration.

Petro Franko
  • 5,603
  • 1
  • 17
  • 18
Farid Nouri Neshat
  • 29,438
  • 6
  • 74
  • 115
  • 16
    This is bad advice. It's gonna be tricky setting `process.env.NODE_ENV` reliably from the app itself. Best set your environment variable properly as Daniel linked below. – M.K. Safi Sep 09 '13 at 19:55
  • 22
    I'm a fan of setting `NODE_ENV` explicitly every time you run the app, as in the second example (`NODE_ENV=production node app.js`). That way you potentially save yourself from some future hair-pulling in the event that you forget to set your local `NODE_ENV` back to `development`. – Jon Feb 15 '14 at 19:52
  • Not so brilliant at all. Every time you run your app you have to add that env var. That sucks. Posted better solution below. – Lukas Liesis Jan 27 '16 at 14:44
  • 3
    Refer to https://www.npmjs.com/package/cross-env for a simple cross-platform solution. `cross-env NODE_ENV=production` works on windows and linux / mac. – AntonB Jun 04 '16 at 13:55
  • @LukasLiesis Not so brilliant at all. Every time you need to change your config you have to edit /etc/environment (if you even can). That sucks. Posted better solution below. – theflowersoftime Jun 16 '16 at 21:43
  • How to use this approach `NODE_ENV=production node app.js`, but using _forever_ instead of _node_ – Gleb Sep 19 '17 at 15:45
  • 1
    @Gleb `NODE_ENV=production forever app.js` should work. – Farid Nouri Neshat Sep 19 '17 at 18:51
  • @FaridNouriNeshat this works but I have one question related. Why this `NODE_ENV=production webpack -p` works while this `NODE_ENV=production && webpack -p` does not? If I write in my shell `myvar='test' && echo "$myvar"` myvar is right, why the NODE_ENV var is is not set/read/whatever-wrong-is-happening? Thank you – Francesco Oct 21 '17 at 14:15
  • When you have something `NODE_ENV=production` without any command(as in `NODE_ENV=production && webpack -p`) it just sets a shell variable, not an env variable. To set a env variable you need to have `export`, without it'll just be a shell variable. Check [this question](https://askubuntu.com/q/26318/32034). – Farid Nouri Neshat Oct 21 '17 at 16:31
  • 1
    Nothing wrong with using process.env.NODE_ENV if you are using a settings file and know what you're doing – Dmitri R117 Sep 30 '18 at 07:04
  • when my pc or server login at that time every time i need to set export NODE_ENV=production why I don't know ? otherwise I got an undefined value – chirag sorathiya May 02 '19 at 07:29
  • For PowerShell should be `$env:NODE_ENV="production"` – Petro Franko Aug 24 '20 at 14:02
140

in package.json:

{
  ...
  "scripts": {
    "start": "NODE_ENV=production node ./app"
  }
  ...
}

then run in terminal:

npm start
wangchi
  • 2,945
  • 1
  • 16
  • 11
  • 45
    @WeDoTDD what are you talking about? These scripts are meant to be used similarly to how makefile works. Using it as this example or as you've mentioned to run gulp is a perfectly reasonable use case. For simple tasks I now don't even use gulp and do it all inside the script, it's much faster to get stuff working and I let webpack do the work which used to be done by gulp. – Marko Gresak Nov 09 '15 at 03:03
  • 1
    Because you end up with inconsistent scripts across all projects which is a maintenance nightmare – PositiveGuy Nov 09 '15 at 14:02
  • 20
    @WTF - What do you mean it's "bad practice" to use scripts in package.json? That's the point of the the scripts: section, to put scripts! Its perfectly valid and eliminates the need for gulp or grunt. All done via command and webpack. – TetraDev May 20 '16 at 22:30
  • 7
    @WTF Using scripts actually greatly improves consistency. You can set up a standard set of commands to be used across multiple project which may not use the same underlying build scripts, libraries, etc. You could at least try to back your point with facts and examples. – Lewis Diamond Aug 16 '16 at 20:12
  • 1
    Not to mention that this is (as far as I know) the only portable way to set the NODE_ENV variable – Overdrivr Nov 16 '16 at 07:21
  • 6
    Putting `NODE_ENV=production` in package.json doesn't make much sense. Running `npm start` in development will run it in production. You might as write your code as if it's always production, since you always run it that way. The one reason I see to do this would be to force other modules (e.g. Express) to run in production mode. Why use environment variables at all if they never change? – Nateowami Jan 23 '17 at 15:54
  • 1
    On Windows it needs to be `"start": "set NODE_ENV=production node ./app"` – Benny Code Feb 16 '17 at 14:28
  • 1
    @Nateowami Because you may want some tasks to know if you're building for prod, or for dev. ie, i have `dev: NODE_ENV=dev`, and then run `npm run dev` when developing, and load api keys based off of that – sqram Mar 28 '18 at 03:21
  • This won't work on Windows, as Benny says, and in Powershell it will break as well, since it uses `$Env:NODE_ENV="development". So this is a bad overall solution. – Anuga May 06 '19 at 09:07
  • @Nateowami What u said is correct but only for your use case, I have 4 environments to manage (sit, uat, pre-prod and prod) and all have different env files. Giving node env in scripts is the only way for me to point out different .env files(as far as I know) – Ubaid Qureshi Nov 21 '20 at 08:32
105

No one mentioned .env in here yet? Make a .env file in your app root, then require('dotenv').config() and read the values. Easily changed, easily read, cross platform.

https://www.npmjs.com/package/dotenv

theflowersoftime
  • 2,546
  • 3
  • 24
  • 32
  • 4
    Weird no one mentions it, best solution in my opinion. Put the environment name in the same file with the rest of the variables. – Asinus Rex Mar 14 '18 at 18:05
  • 4
    Setting NODE_ENV in .env file won't work. See this: https://github.com/motdotla/dotenv/issues/328 – Michael Zelensky Jan 28 '19 at 10:51
  • 1
    For me setting `"mode": "production"` in the `.env` file worked. – DarkLite1 Jun 09 '20 at 07:22
  • Also add .env to .gitignore so that it does not overwrite the .env when pushing code to production. i.e. The .env should remain unchanged when pushing code around environments. – kiwicomb123 Nov 20 '21 at 05:10
56

export NODE_ENV=production is bad solution, it disappears after restart.

if you want not to worry about that variable anymore - add it to this file:

/etc/environment

don't use export syntax, just write (in new line if some content is already there):

NODE_ENV=production

it works after restart. You will not have to re-enter export NODE_ENV=production command anymore anywhere and just use node with anything you'd like - forever, pm2...

For heroku:

heroku config:set NODE_ENV="production"

which is actually default.

Lukas Liesis
  • 24,652
  • 10
  • 111
  • 109
  • 2
    Maintenance nightmare. What about a box where you don't have permissions to /etc? – theflowersoftime Jun 16 '16 at 21:41
  • 1
    I personally use `NODE_ENV=production gulp bundle-production-app` to bundle production ready script, in server NODE_ENV is in server's environment and in dev machine it's not there. In some machines it's nightmare if it's not set and you expect to have it set *always*. In some, you expect not to have it, so you don't add. Anyways, while doing UIs i make it clear if it's in development mode so you never have a question if it's on or off. If NODE_ENV is !== production it's in your face that you are in other mode, so no nightmare at all. All clear, all good. – Lukas Liesis Jul 12 '16 at 10:08
  • 1
    +1 for talking about how to make it persist. I wonder how many people have set it only in the current session thinking it will persist. What about *before* a restart? If you want to set it right away, should you put it in `/etc/environment` *and* run `export NODE_ENV=production`? – Nateowami Jan 23 '17 at 16:03
46

To not have to worry whether you are running your scripts on Windows, Mac or Linux install the cross-env package. Then you can use your scripts easily, like so:

"scripts": {
    "start-dev": "cross-env NODE_ENV=development nodemon --exec babel-node -- src/index.js",
    "start-prod": "cross-env NODE_ENV=production nodemon --exec babel-node -- src/index.js"
}

Massive props to the developers of this package.

npm install --save-dev cross-env
icl7126
  • 5,740
  • 4
  • 53
  • 51
Notorious
  • 3,057
  • 3
  • 23
  • 33
  • 3
    How will it work if it's installed as dev dependency? In production, npm packages should be installed with --production flag which won't install cross-env as it's a dev dependency. – Darvesh Dec 19 '20 at 10:23
  • This answer hepled me but not in a way it helpes everyone) ```"tsc && NODE_ENV=production nodemon ..."``` - *working*. ```"NODE_ENV=production tsc && nodemon ..."``` - *not working* – MadaShindeInai Jan 06 '22 at 15:07
23
heroku config:set NODE_ENV="production"
david_adler
  • 9,690
  • 6
  • 57
  • 97
10

For Windows Powershell use this command

$env:NODE_ENV="production" ; node app.js
Harikrishnan
  • 9,688
  • 11
  • 84
  • 127
7

On OSX I'd recommend adding export NODE_ENV=development to your ~/.bash_profile and/or ~/.bashrc and/or ~/.profile.

Personally I add that entry to my ~/.bashrc and then have the ~/.bash_profile ~/.profile import the contents of that file, so it's consistent across environments.

After making these additions, be sure to restart your terminal to pick up settings.

Vincil Bishop
  • 1,594
  • 17
  • 21
3

In order to have multiple environments you need all of the answers before (NODE_ENV parameter and export it), but I use a very simple approach without the need of installing anything. In your package.json just put a script for each env you need, like this:

...
"scripts": {
    "start-dev": "export NODE_ENV=dev && ts-node-dev --respawn --transpileOnly ./src/app.ts",
    "start-prod": "export NODE_ENV=prod && ts-node-dev --respawn --transpileOnly ./src/app.ts"
  }
 ...

Then, to start the app instead of using npm start use npm run script-prod.

In the code you can access the current environment with process.env.NODE_ENV.

Voila.

rmpt
  • 606
  • 1
  • 4
  • 24
3

Windows CMD -> set NODE_ENV=production

Windows Powershell -> $env:NODE_ENV="production"

MAC -> export NODE_ENV=production

Janith Udara
  • 625
  • 1
  • 7
  • 15
2

If you are on windows. Open your cmd at right folder then first

set node_env={your env name here}

hit enter then you can start your node with

node app.js

it will start with your env setting

garenyondem
  • 541
  • 9
  • 24
  • 1
    won't it disappear after restart? Don't have windows, can't try myself. – Lukas Liesis Mar 05 '16 at 06:26
  • If you are asking about node restart no, it won't disappear until you completely close the command prompt. But if Windows Server restarts ofc it will disappear. – garenyondem Mar 05 '16 at 11:14
  • 2
    talking about OS restart. That's why i better find another way to stop wondering every time windows updates installed, or just any restart, about this issue again and again. – Lukas Liesis Mar 06 '16 at 12:17
2

If you using webpack in your application, you can simply set it there, using DefinePlugin...

So in your plugin section, set the NODE_ENV to production:

plugins: [
  new webpack.DefinePlugin({
    'process.env.NODE_ENV': '"production"',
  })
]
Alireza
  • 100,211
  • 27
  • 269
  • 172
1
npm start --mode production
npm start --mode development

With process.env.NODE_ENV = 'production'

Tính Ngô Quang
  • 4,400
  • 1
  • 33
  • 33
0

Daniel has a fantastic answer which is the better approach for the correct deployment (set and forget) process.

For those using express. You can use grunt-express-server which is fantastic as well. https://www.npmjs.org/package/grunt-express-server

Jesse
  • 307
  • 2
  • 5
0

You can run by environment as below,

NODE_ENV=production npm run start
Furkan Öztürk
  • 1,178
  • 11
  • 24
0

I don't see a Docker solution explicitly mentioned anywhere; hopefully this helps someone:

In Dockerfile:

FROM node:16.11-alpine3.14 AS production
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
...
rinogo
  • 8,491
  • 12
  • 61
  • 102
0

NODE_ENV works like any other environment variable. How to set it depends on the platform being used.

On Linux and OSX: export NODE_ENV=production
On Windows: $env:NODE_ENV = 'production
Omar Saade
  • 320
  • 2
  • 8