294

I'm trying to follow a tutorial on NodeJS. I don't think I missed anything but whenever I call the process.env.NODE_ENV the only value I get back is undefined. According to my research the default value should be development. How is this value dynamically set and where is it set initially?

Flip
  • 6,233
  • 7
  • 46
  • 75
basheps
  • 10,034
  • 11
  • 36
  • 45
  • 3
    to set NODE_ENV for heroku apps you can use: `heroku config:set NODE_ENV="production"` – Connor Leech Jun 17 '14 at 23:09
  • 27
    Although the answers below will solve the problem temporarily by setting the environment variable, the bigger lesson here should be that you can never know whether any environment variable will be set... So write your code accordingly and test whether it's set and if so, to what. Don't make assumptions about it. – Stijn de Witt Dec 16 '15 at 01:17
  • Does this answer your question? [How to set NODE\_ENV to production/development in OS X](https://stackoverflow.com/questions/9198310/how-to-set-node-env-to-production-development-in-os-x) – Michael Freidgeim Jan 04 '21 at 11:45

22 Answers22

298

process.env is a reference to your environment, so you have to set the variable there.

To set an environment variable in Windows:

SET NODE_ENV=development

on macOS / OS X or Linux:

export NODE_ENV=development
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
James Tikalsky
  • 3,856
  • 1
  • 21
  • 12
  • This worked, only on my OS X the word 'EXPORT' needed to be lowercase. Thanks. – basheps Jun 19 '12 at 15:26
  • 9
    you might add that if NODE_ENV is not set the app behaves like in "development" mode – Rocco Sep 21 '13 at 20:53
  • 1
    For Linux, vi ~/.bash_profile, then insert NODE_ENV=development and save. – stonyau Oct 12 '14 at 03:41
  • 17
    In case anyone else struggles... there is a difference between "SET V = VAL" and "SET V=VAL". Spaces matter. – willem Mar 14 '16 at 06:39
  • 5
    Note that the module "cross-env" to do similar to the above, and it will work on both OSX and Windows: "cross-env NODE_ENV=development". You need to install cross-env first: "npm install cross-env --save". Have that in a script in your package.json and you're good to go on both platforms. – Antonio Brandao Jun 09 '16 at 15:59
  • 13
    Didn't work for me. I executed `export NODE_ENV=development` on my Mac terminal before doing a `react-native run-ios` from the same terminal. When debugging, the value of `process.env.NODE_ENV` is undefined. – Ash Jun 26 '19 at 05:54
  • Nice one. I was missing the export keyword before the vars. – Firmino Changani Dec 24 '19 at 20:58
  • @Ash You have to restart your terminal for the new env vars to take effect. – Torsten Barthel Aug 20 '20 at 23:27
  • I didn't have to restart my terminal to get it working – Andresa Martins Jan 11 '21 at 11:39
  • @Rocco Just an opinion, but I would say the opposite - make prod the default, and dev opt-in. This is because, if the wrong mode is used during the development, the developer will notice immediately. However, if a new employee who doesn't yet fully understand the system accidentally omits `NODE_ENV` and runs dev mode in prod (which for some setups skip things like minification or log sensitive data) then you could easily go weeks without noticing the issue. – aggregate1166877 Nov 09 '22 at 02:25
  • 1
    @aggregate1166877 agree. just over 9 years later I would also suggest making PROD the default :) however the OP expected the default to be `development` – Rocco Nov 09 '22 at 17:07
107

tips

in package.json:

"scripts": {
  "start": "set NODE_ENV=dev && node app.js"
 }

in app.js:

console.log(process.env.NODE_ENV) // dev
console.log(process.env.NODE_ENV === 'dev') // false
console.log(process.env.NODE_ENV.length) // 4 (including a space at the end) 

so, this may better:

"start": "set NODE_ENV=dev&& node app.js"

or

console.log(process.env.NODE_ENV.trim() === 'dev') // true
kenberkeley
  • 8,449
  • 3
  • 35
  • 25
  • 3
    What you can do is this, so you don't have to trim: `"start": "set NODE_ENV=dev&& node app.js"` – Bernardo Dal Corno Dec 19 '18 at 15:56
  • 3
    Excellent observation, `console.log(process.env.NODE_ENV.length)` **// 4 (including a space at the end)** – gregn3 Jun 08 '20 at 14:01
  • 1
    This is safer: `console.log(('' + process.env.NODE_ENV).trim() === 'dev') // true` , as it will not throw an error even if **process.env.NODE_ENV** is undefined. – gregn3 Jun 08 '20 at 14:14
  • 4
    Using `SET` makes the start-up script limited to Windows. – Quanta Sep 29 '20 at 17:47
  • 3
    You can do this to solve the space issue: `"start": "export NODE_ENV='dev' && ..."`. So put the env between two `'`. – erkage Jul 11 '21 at 08:46
  • 2
    **NEVER** hardcode windows-specific stuff inside package.json – Roko C. Buljan Nov 24 '21 at 15:23
  • You should use the [optional chaining (?.)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining) operator `process.env.NODE_ENV?.trim()` in case variable is `undefined`. – Igor Sukharev Mar 24 '23 at 21:02
71

For people using *nix (Linux, OS X, etc.), there's no reason to do it via a second export command, you can chain it as part of the invoking command:

NODE_ENV=development node server.js

Easier, no? :)

mlaccetti
  • 1,726
  • 2
  • 18
  • 17
53

We ran into this problem when working with node on Windows.

Rather than requiring anyone who attempts to run the app to set these variables, we provided a fallback within the application.

var environment = process.env.NODE_ENV || 'development';

In a production environment, we would define it per the usual methods (SET/export).

Jacob
  • 655
  • 5
  • 4
  • 7
    This is the most pragmatic solution. – druskacik Sep 14 '19 at 15:39
  • What if the value of **process.env.NODE_ENV** is undefined and the user wants to change development to production in .env file? – Kiran RS Mar 17 '21 at 13:21
  • this works great when using typescript strictNullChecks – java-addict301 Sep 17 '21 at 03:34
  • @KiranRS You environment should not be decided by your .env file. On the contrary, your environment decides which .env file to load (.env.testing, .env.prod, etc). So, if the user wants to run production, it should set `process.env.NODE_ENV` system-wise. – Ricardo Yubal Jun 09 '23 at 22:14
23

You can use the cross-env npm package. It will take care of trimming the environment variable, and will also make sure it works across different platforms.

In the project root, run:

npm install cross-env

Then in your package.json, under scripts, add:

"start": "cross-env NODE_ENV=dev node your-app-name.js"

Then in your terminal, at the project root, start your app by running:

npm start

The environment variable will then be available in your app as process.env.NODE_ENV, so you could do something like:

if (process.env.NODE_ENV === 'dev') {
  // Your dev-only logic goes here
}
Liran H
  • 9,143
  • 7
  • 39
  • 52
  • 2
    I don't think this works. Tried it in my current project and NODE_ENV is still undefined. This might need some more config to work it seems. – Aakash Thakur May 05 '19 at 09:46
  • 2
    **npm install --save-dev cross-env** – DalSoft Feb 08 '20 at 00:16
  • 1
    for me somehow the accepted answer was not working, but this <3 – Chathura Buddhika Apr 06 '21 at 13:20
  • 1
    for me it is not working either on local machine windows. NODE_ENV is still undefined – rendom Sep 12 '21 at 07:29
  • @rendom You still need to declare the value you want to set in the .env file. For example here you would want `NODE_ENV=""` in .env file and then it would be set with the value you assign it in the run script – hanku8 Nov 13 '22 at 13:19
17

in package.json we have to config like below (works in Linux and Mac OS)

the important thing is "export NODE_ENV=production" after your build commands below is an example:

  "scripts": {
     "start": "export NODE_ENV=production && npm run build && npm run start-server",
     "dev": "export NODE_ENV=dev && npm run build && npm run start-server",
  } 
  • for dev environment, we have to hit "npm run dev" command

  • for a production environment, we have to hit "npm run start" command

D V Yogesh
  • 3,337
  • 1
  • 28
  • 39
  • When I do this I get the error: 'export' is not recognized as an internal or external command, operable program or batch file. – Casivio Mar 03 '21 at 19:15
  • @Casivio on Windows, use `set` instead of `export`. `"scripts": { "start": "set NODE_ENV=production && npm run build && npm run start-server" }` – cweave Jan 02 '22 at 06:08
15

In macOS for those who are using the express version 4.x.x and using the DOTENV plugin, need to use like this:

  1. After installing the plugin import like the following in the file where you init the application: require('dotenv').config({path: path.resolve(__dirname+'/.env')});

  2. In the root directory create a file '.env' and add the varaiable like:

    NODE_ENV=development or NODE_ENV = development

NRP
  • 452
  • 1
  • 5
  • 12
10

As early as possible in your application, require and configure dotenv.

require('dotenv').config()

8

Must be the first require in app.js

npm install dotenv

require("dotenv").config();
MonsterPHP
  • 89
  • 2
  • 3
7

In UBUNTU use:

$ export NODE_ENV=test

Gilbert Flamino
  • 101
  • 2
  • 2
  • What indicated by @gilbert-flamino worked for me. Just to be more explicit. On Windows: `"dev": "set NODE_ENV=development&& npx nodemon bin/www",` On Ubuntu: `"dev": "export NODE_ENV=development&& npx nodemon bin/www",` – dixoen Jun 21 '22 at 15:40
5

install dotenv module ( npm i dotenv --save )

require('dotenv').config() //write inside the file where you will use the variable

console.log(process.env.NODE_ENV) // returns value stored in .env file

PRIYESH N D
  • 51
  • 1
  • 3
2

In my case, I have a node app. The way I have structured it is that I have client folder and server folder. I had my .env file inline with these two folder. My server file needs the .env file. It was returning undefined because it did not live inside the server file. It was an oversight.

App
-client
-server
-.env

Instead I moved .env inside server file like so:

App
-client
-server
 |-.env <---here
 |-package.json
 |-and the rest of the server files...

(before this - ofcourse have the dotenv npm package installed and follow its doc)
Gel
  • 2,866
  • 2
  • 18
  • 25
1

It is due to OS

In your package.json, make sure to have your scripts(Where app.js is your main js file to be executed & NODE_ENV is declared in a .env file).Eg:

"scripts": {
    "start": "node app.js",
    "dev": "nodemon server.js",
    "prod": "NODE_ENV=production & nodemon app.js"
  }

For windows

Also set up your .env file variable having NODE_ENV=development

If your .env file is in a folder for eg.config folder make sure to specify in app.js(your main js file)

const dotenv = require('dotenv'); dotenv.config({ path: './config/config.env' });

1

You can use the dotenv package from npm, here is the link: https://www.npmjs.com/package/dotenv

Which allows you to place all your configuration in a .env file

Ahsan Farooq
  • 819
  • 9
  • 10
  • 1
    Looks like envalid no longer ships with dotenv so you now need to manually install / call this before you invoke envalid's cleanEnv(). This caught me out so leaving this here for others – Stretch0 Sep 20 '21 at 11:23
0

If you faced this probem in React, you need react-scripts@0.2.3 and higher. Also for other environment variables than NODE_ENV to work in React, they need to be prefixed with REACT_APP_.

Daniel B
  • 4,145
  • 1
  • 21
  • 21
0

For me, the issue was that I was using the pkg library to turn my app into an executable binary. In that case, the accepted solutions didn't work. However, using the following code solved my problem:

const NODE_ENV = (<any>process).pkg ? 'production' : process.env.NODE_ENV;

I found this solution here on GitHub.

Jon
  • 2,456
  • 21
  • 28
0

In Electron Js

"scripts": {
    "start": "NODE_ENV=development electron index.js",
},
0

If you define any function with the name process then that may also cause this issue.

Saurabh Joshi
  • 71
  • 1
  • 8
0

Defining process.env.NODE_ENV in package.json for Windows/Mac/Linux:

Here's what worked for me on my Mac (MacBook Pro 2019, 16 inch, Big Sur):

"scripts": {
    "build": "export NODE_ENV=prod || set NODE_ENV=prod&& npx eslint . && node --experimental-json-modules ./backend/app.js && gulp",
},

Using the export NODE_ENV=prod || set NODE_ENV=prod&& string may work in Windows and Linux but I haven't tested that.

If someone could confirm that would be great.

Unfortunately using the cross-env npm package did NOT work for me at all in my package.json file and I spend a long time on my Mac trying to make this work.

0

I also faced this issue. I moved .env file to the root folder (not the project folder, a level higher) and it worked out.

Check it. it might help you as well

HMilbradt
  • 3,980
  • 16
  • 31
Daniil
  • 21
  • 4
0

Well, this answer could help you and it works with these stack, Node.js with Next.js and tRPC.

Steps:

  1. You have to install dotenv package to access the .env data through your process.env object. So if you are using npm you have to type: npm install dotenv
  2. Then, you have to find the folder where is located your environment variables validation, it usually have a validator library like Zod, the file in this folder could have the extension .js or .mjs. Here you have to add this code at the beginning:
// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();
Ángel Ugarte
  • 91
  • 1
  • 4
-4

You can also set it by code, for example:

process.env.NODE_ENV = 'test';

joaquindev
  • 143
  • 1
  • 5
  • 80
    I STRONGLY discourage anyone from ever changing the environment identifier in application logic. You never want the application to suddenly think it is something else than it really is. This should only ever be changed on system-level, as many of the other answers suggest. – Kafoso Jul 07 '15 at 13:00
  • 7
    You might want to read about 12 factor apps: https://12factor.net/config. This code would be a violation of that. There are good reasons to keep your config separate from your code. – jcollum Jul 28 '17 at 16:00
  • 2
    It might be useful only for automated testing, but even then it could be abstracted and injected into your main code, instead of being read directly from env. – Angelos Pikoulas Nov 21 '18 at 18:21
  • 1
    Let's not downvote this answer so much that the informative comment by @Kafoso gets diminished. Or add this information to some well-voted answer. – Vibhor Dube Jun 17 '20 at 09:56
  • Well, what if someone packs a web application with webpack and runs it in nginx? – Mario Eis Sep 24 '22 at 16:12