Environment Variables

Environment variables are global system variables accessible by all the processes running under the Operating System (OS). Environment variables are useful to store system-wide values such as the directories to search for executable programs (PATH), OS version, Network Information, and custom variables. These env variables are passed at build time and used at the runtime of an app.

This guide is divided into two sections:

  1. Setting environment variables
  2. Using environment variables in React and Angular

Setting environment variables

By default, Nx will load any environment variables you place in the following files:

  1. apps/my-app/.local.env
  2. apps/my-app/.env.local
  3. apps/my-app/.env
  4. .local.env
  5. .env.local
  6. .env

Note: Order is important. Nx will move through the above list, ignoring files it can't find, and loading environment variables into the current process for the ones it can find. If it finds a variable that has already been loaded into the process, it will ignore it. It does this for two reasons:

  1. Developers can't accidentally overwrite important system level variables (like NODE_ENV)
  2. Allows developers to create .env.local or .local.env files for their local environment and override any project defaults set in .env

For example:

  1. apps/my-app/.env.local contains NX_API_URL=http://localhost:3333
  2. apps/my-app/.env contains NX_API_URL=https://api.example.com
  3. Nx will first load the variables from apps/my-app/.env.local into the process. When it tries to load the variables from apps/my-app/.env, it will notice that NX_API_URL already exists, so it will ignore it.

We recommend nesting your app specific env files in apps/your-app, and creating workspace/root level env files for workspace-specific settings (like the Nx Cloud token).

Pointing to custom env files

If you want to load variables from env files other than the ones listed above:

  1. Use the env-cmd package: env-cmd -f .qa.env nx serve
  2. Use the envFile option of the run-commands builder and execute your command inside of the builder

Ad-hoc variables

You can also define environment variables in an ad-hoc manner using support from your OS and shell.

Unix systems

In Unix systems, we need to set the environment variables before calling a command.

Let's say that we want to define an API URL for the application to use:

NX_API_URL=http://localhost:3333 nx build myapp

Windows (cmd.exe)

set "NX_API_URL=http://localhost:3333" && nx build myapp

Windows (Powershell)

($env:NX_API_URL = "http://localhost:3333") -and (nx build myapp)

Using environment variables

Handling of environment variables can differ between Nx plugins. For React applications, usage of variables in TS/JS files and index.html is automatically included in the build process; whereas in Angular applications, environment variables require extra setup to use, and by default Angular encourages using environment.*.ts files in combination with fileReplacement option during build.

Using environment variables in React applications

In React applications (e.g. those using @nrwl/web:webpack or @nrwl/next:build executors for build target), Nx includes the following variables in the build process:

  • NODE_ENV
  • Variables prefixed with NX_, such as NX_CUSTOM_VAR

Defining environment variables can vary between OSes. It's also important to know that this is temporary for the life of the shell session.

Using environment variables in index.html

Nx supports interpolating environment variables into your index.html file for React and Web applications.

To interpolate an environment variable named NX_DOMAIN_NAME into your index.html, surround it with % symbols like so:

1<html>
2  <body>
3    <p>The domain name is %NX_DOMAIN_NAME%.</p>
4  </body>
5</html>

Using environment variables in Angular applications

By default, Angular only provides the NODE_ENV variable when building the application. You may use process.env.NODE_ENV anywhere in your TS/JS source, and the build will inline this value in the output chunks.

Other variables, such as those prefixed by NX_ will not work in Angular. To add support for other environment variables, do the following.

First, install @types/node so we can use process.env in our code.

npm install --save-dev @types/node

# Or with yarn
yarn add --dev @types/node

Next, update the build and serve targets (in project.json or angular.json file), to the following.

1{
2  "build": {
3    // NOTE: change the executor to one that supports custom webpack config.
4    "executor": "@nrwl/angular:webpack-browser",
5    // snip
6    "options": {
7      // NOTE: This file needs to be created.
8      "customWebpackConfig": {
9        "path": "apps/myapp/webpack.config.js"
10      }
11      // snip
12    }
13  },
14  "serve": {
15    // NOTE: use dev-server that supports custom webpack config.
16    "executor": "@nrwl/angular:webpack-server"
17    // snip
18  }
19}

Then, we can use DefinePlugin in our custom webpack.

1// apps/myapp/webpack.config.js
2const webpack = require('webpack');
3
4function getClientEnvironment(configuration) {
5  // Grab NODE_ENV and NX_* environment variables and prepare them to be
6  // injected into the application via DefinePlugin in webpack configuration.
7  const NX_APP = /^NX_/i;
8
9  const raw = Object.keys(process.env)
10    .filter((key) => NX_APP.test(key))
11    .reduce(
12      (env, key) => {
13        env[key] = process.env[key];
14        return env;
15      },
16      {
17        NODE_ENV: process.env.NODE_ENV || configuration,
18      }
19    );
20
21  // Stringify all values so we can feed into webpack DefinePlugin
22  return {
23    'process.env': Object.keys(raw).reduce((env, key) => {
24      env[key] = JSON.stringify(raw[key]);
25      return env;
26    }, {}),
27  };
28}
29
30module.exports = (config, options, context) => {
31  config.plugins.push(
32    new webpack.DefinePlugin(getClientEnvironment(context.configuration))
33  );
34  return config;
35};

Now, when we define variables in our .env file, such as...

# apps/myapp/.env
NX_API_URL=http://localhost:3333

Finally, We can use environment variables in our code. For example,

1// apps/myapp/src/main.ts
2import { enableProdMode } from '@angular/core';
3import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4import { AppModule } from './app/app.module';
5
6if (process.env['NODE_ENV'] === 'production') {
7  enableProdMode();
8}
9
10// This is defined in our .env file.
11console.log('>>> NX_API_URL', process.env['NX_API_URL']);
12
13platformBrowserDynamic()
14  .bootstrapModule(AppModule)
15  .catch((err) => console.error(err));

You should also update tsconfig.apps.json and tsconfig.spec.json files to include node types.

1{
2  "extends": "./tsconfig.json",
3  "compilerOptions": {
4    // snip
5    "types": ["node"]
6  }
7  // snip
8}

Using environment variables in index.html

While you cannot use variable in index.html, one workaround for this is to create different index.*.html files, such as index.prod.html, then swap it in different environments.

For example in project.json (or angular.json),

1{
2  "build": {
3    "executor": "@angular-devkit/build-angular:browser",
4    // snip
5    "configurations": {
6      "production": {
7        // snip
8        "fileReplacements": [
9          {
10            "replace": "apps/myapp/src/environments/environment.ts",
11            "with": "apps/myapp/src/environments/environment.prod.ts"
12          },
13          {
14            "replace": "apps/myapp/src/index.html",
15            "with": "apps/myapp/src/index.prod.html"
16          }
17        ]
18      }
19    }
20  }
21}

You can also customize your webpack configuration, similar to using DefinePlugin above. This approach will require post-processing the index.html file, and is out of scope for this guide.

Summary

Nx supports setting environment variables from env files in your projects and workspace root. If there are multiple env files, then the values from the application (e.g. <root>/apps/myapp/.env) takes precedence over the values from workspace (e.g. <root>/.env). You can also set local overrides in .env.local or .local.env files.

Usage of environment variables different between React and Angular applications, so make sure your usage matches the support from each Framework.