[node.js] How to set environment variables from within package.json?

How to set some environment variables from within package.json to be used with npm start like commands?

Here's what I currently have in my package.json:

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "tagove start"
  }
  ...
}

I want to set environment variables (like NODE_ENV) in the start script while still being able to start the app with just one command, npm start.

This question is related to node.js npm package.json npm-scripts

The answer is


Just use NPM package cross-env. Super easy. Works on Windows, Linux, and all environments. Notice that you don't use && to move to the next task. You just set the env and then start the next task. Credit to @mikekidder for the suggestion in one of the comments here.

From documentation:

{
  "scripts": {
    "build": "cross-env NODE_ENV=production OTHERFLAG=myValue webpack --config build/webpack.config.js"
  }
}

Notice that if you want to set multiple global vars, you just state them in succession, followed by your command to be executed.

Ultimately, the command that is executed (using spawn) is:

webpack --config build/webpack.config.js

The NODE_ENV environment variable will be set by cross-env


I just wanted to add my two cents here for future Node-explorers. On my Ubuntu 14.04 the NODE_ENV=test didn't work, I had to use export NODE_ENV=test after which NODE_ENV=test started working too, weird.

On Windows as have been said you have to use set NODE_ENV=test but for a cross-platform solution the cross-env library didn't seem to do the trick and do you really need a library to do this:

export NODE_ENV=test || set NODE_ENV=test&& yadda yadda

The vertical bars are needed as otherwise Windows would crash on the unrecognized export NODE_ENV command. I don't know about the trailing space, but just to be sure I removed them too.


@luke's answer was almost the one I needed! Thanks.

As the selected answer is very straightforward (and correct), but old, I would like to offer an alternative for importing variables from a .env separate file when running your scripts and fixing some limitations to Luke's answer. Try this:

::: .env file :::

# This way, you CAN use comments in your .env files
NODE_PATH="src/"

# You can also have extra/empty lines in it
SASS_PATH="node_modules:src/styles"

Then, in your package json, you will create a script that will set the variables and run it before the scripts you need them:

::: package.json :::

scripts: {
  "set-env": "export $(cat .env | grep \"^[^#;]\" |xargs)",
  "storybook": "npm run set-env && start-storybook -s public"
}

Some observations:

  • The regular expression in the grep'ed cat command will clear the comments and empty lines.

  • The && don't need to be "glued" to npm run set-env, as it would be required if you were setting the variables in the same command.

  • If you are using yarn, you may see a warning, you can either change it to yarn set-env or use npm run set-env --scripts-prepend-node-path && instead.

Different environments

Another advantage when using it is that you can have different environment variables.

scripts: {
  "set-env:production": "export $(cat .production.env | grep \"^[^#;]\" |xargs)",
  "set-env:development": "export $(cat .env | grep \"^[^#;]\" |xargs)",
}

Please, remember not to add .env files to your git repository when you have keys, passwords or sensitive/personal data in them!


Although not directly answering the question I´d like to share an idea on top of the other answers. From what I got each of these would offer some level of complexity to achieve cross platform independency.

On my scenario all I wanted, originally, to set a variable to control whether or not to secure the server with JWT authentication (for development purposes)

After reading the answers I decided simply to create 2 different files, with authentication turned on and off respectively.

  "scripts": {
    "dev": "nodemon --debug  index_auth.js",
    "devna": "nodemon --debug  index_no_auth.js",
  }

The files are simply wrappers that call the original index.js file (which I renamed to appbootstrapper.js):

//index_no_auth.js authentication turned off
const bootstrapper = require('./appbootstrapper');
bootstrapper(false);

//index_auth.js authentication turned on
const bootstrapper = require('./appbootstrapper');
bootstrapper(true);

class AppBootStrapper {

    init(useauth) {
        //real initialization
    }
}

Perhaps this can help someone else


This will work in Windows console:

"scripts": {
  "setAndStart": "set TMP=test&& node index.js",
  "otherScriptCmd": "echo %TMP%"
}

npm run aaa

output: test

See this answer for details.


Note : In order to set multiple environment variable, script should goes like this

  "scripts": {
    "start": "set NODE_ENV=production&& set MONGO_USER=your_DB_USER_NAME&& set MONGO_PASSWORD=DB_PASSWORD&& set MONGO_DEFAULT_DATABASE=DB_NAME&& node app.js",
  },

use git bash in windows. Git Bash processes commands differently than cmd.

Most Windows command prompts will choke when you set environment variables with NODE_ENV=production like that. (The exception is Bash on Windows, which uses native Bash.) Similarly, there's a difference in how windows and POSIX commands utilize environment variables. With POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%. - cross-env doc

{
  ...
  "scripts": {
    "help": "tagove help",
    "start": "env NODE_ENV=production tagove start"
  }
  ...
}

use dotenv package to declare the env variables


You should not set ENV variables in package.json. actionhero uses NODE_ENV to allow you to change configuration options which are loaded from the files in ./config. Check out the redis config file, and see how NODE_ENV is uses to change database options in NODE_ENV=test

If you want to use other ENV variables to set things (perhaps the HTTP port), you still don't need to change anything in package.json. For example, if you set PORT=1234 in ENV and want to use that as the HTTP port in NODE_ENV=production, just reference that in the relevant config file, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}

{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}

suddenly i found that actionhero is using following code, that solved my problem by just passing --NODE_ENV=production in start script command option.

if(argv['NODE_ENV'] != null){
  api.env = argv['NODE_ENV'];
} else if(process.env.NODE_ENV != null){
  api.env = process.env.NODE_ENV;
}

i would really appreciate to accept answer of someone else who know more better way to set environment variables in package.json or init script or something like, where app bootstrapped by someone else.


Because I often find myself working with multiple environment variables, I find it useful to keep them in a separate .env file (make sure to ignore this from your source control). Then (in Linux) prepend export $(cat .env | xargs) && in your script command before starting your app.

Example .env file:

VAR_A=Hello World
VAR_B=format the .env file like this with new vars separated by a line break

Example index.js:

console.log('Test', process.env.VAR_A, process.env.VAR_B);

Example package.json:

{
  ...
  "scripts": {
    "start": "node index.js",

    "env-linux": "export $(cat .env | xargs) && env",
    "start-linux": "export $(cat .env | xargs) && npm start",

    "env-windows": "(for /F \"tokens=*\" %i in (.env) do set %i)",
    "start-windows": "(for /F \"tokens=*\" %i in (.env) do set %i) && npm start",

  }
  ...
}

Unfortunately I can't seem to set the environment variables by calling a script from a script -- like "start-windows": "npm run env-windows && npm start" -- so there is some redundancy in the scripts.

For a test you can see the env variables by running npm run env-linux or npm run env-windows, and test that they make it into your app by running npm run start-linux or npm run start-windows.


UPDATE: This changes in npm v7 due to npm RFC 21.


npm (and yarn) passes a lot of data from package.json into scripts as environment variables. Use npm run env to see them all. This is documented in https://docs.npmjs.com/misc/scripts#environment and is not only for "lifecycle" scripts like prepublish but also any script executed by npm run.

You can access these inside code (e.g. process.env.npm_package_config_port in JS) but they're already available to the shell running the scripts so you can also access them as $npm_... expansions in the "scripts" (unix syntax, might not work on windows?).

The "config" section seems intended for this use:

  "name": "myproject",
  ...
  "config": {
    "port": "8010"
  },
  "scripts": {
    "start": "node server.js $npm_package_config_port",
    "test": "wait-on http://localhost:$npm_package_config_port/ && node test.js http://localhost:$npm_package_config_port/"
  } 

An important quality of these "config" fields is that users can override them without modifying package.json!

$ npm run start

> [email protected] start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8010

$ npm config set myproject:port 8020
$ git diff package.json  # no change!
$ cat ~/.npmrc
myproject:port=8020

$ npm run start

> [email protected] start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8020

See npm config and yarn config docs.
It appears that yarn reads ~/.npmrc so npm config set affects both, but yarn config set writes to ~/.yarnrc, so only yarn will see it :-(


For a larger set of environment variables or when you want to reuse them you can use env-cmd.

./.env file:

# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}

Try this on Windows by replacing YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to npm

What does 'x packages are looking for funding' mean when running `npm install`? error: This is probably not a problem with npm. There is likely additional logging output above Module not found: Error: Can't resolve 'core-js/es6' Browserslist: caniuse-lite is outdated. Please run next command `npm update caniuse-lite browserslist` ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.2.0 but 3.2.1 was found instead DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean` What exactly is the 'react-scripts start' command? On npm install: Unhandled rejection Error: EACCES: permission denied Difference between npx and npm?

Examples related to package.json

SyntaxError: Cannot use import statement outside a module Module not found: Error: Can't resolve 'core-js/es6' Can not find module “@angular-devkit/build-angular” Error: EPERM: operation not permitted, unlink 'D:\Sources\**\node_modules\fsevents\node_modules\abbrev\package.json' Field 'browser' doesn't contain a valid alias configuration How do I add a custom script to my package.json file that runs a javascript file? "unexpected token import" in Nodejs5 and babel? Start script missing error when running npm start How to use private Github repo as npm dependency How to set environment variables from within package.json?

Examples related to npm-scripts

Start script missing error when running npm start How to set environment variables from within package.json?