Getting environment variables to your web application
Tags: buildtools, environmentvariables, parcel, webpack
Published: 2019-12-02 16:21:44

---
title: Getting environment variables to your web application
published: true
description: Summarize how you can get an environment variable into your web application's code.
tags: build tools, environment variables, parcel, webpack
---

# Getting environment variables to your web application

It is often useful during development to inform your build process that it is working in development mode or production mode. And there are multiple ways to do this, e.g. you can often specify them on the command line, use an environment variable, or put them all together in a `.env` file.

When you are developing a `node.js` application, getting access to these environment variables in your code is also easy, for example by using `process.env.SOME_VAR`, optionally combined with [dotenv](https://www.npmjs.com/package/dotenv) to read those `.env` files before startup.

However, when you need those environment variables also in your web application, e.g. to specify the URL for the production or development service, it is less well documented if you don't know where to look. As it turns out, fortunately, it is not too difficult either:

## Parcel

[Parcel](https://parceljs.org) is a very easy to use build tool, which transpiles and minifies your JavaScript or TypeScript code, CSS files, etc. without any configuration. But as it happens, Parcel also exposes your environment variables to your web application's code. So you can use `process.env.SOME_VAR` directly in your JavaScript code. In case you are working with TypeScript, you need to add a declaration for it too, e.g.

```ts
declare const process: {
  env: {
    SOME_VAR: string;
  };
};
```

## Webpack

[Webpack](https://webpack.js.org) is also a very popular choice to build your application, but requires much more configuration too. So in order to pass environment variables to your web application code, you need to use a default Webpack plugin, the [DefinePlugin](https://webpack.js.org/plugins/define-plugin) (see also [here](https://blog.johnnyreilly.com/2016/07/using-webpacks-defineplugin-with-typescript.html)). For example, your webpack config file could look as follows (when you use TypeScript). Note that you use `JSON.stringify` to pass the value of your variable.

```js
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

// Import environment variables into your build configuration.
module.exports = (env = {}) => {
  const plugins = [
    new HtmlWebpackPlugin({
      meta: {
        description: 'MY_DESCRIPTION',
      },
      title: 'MY_TITLE',
      favicon: './src/assets/favicon.ico',
    }),
    new webpack.HotModuleReplacementPlugin(),
  ];
  // In non-production environment, set the SERVICE_URL
  if (!env.production) {
    plugins.push(
      new webpack.DefinePlugin({
        SERVICE_URL: JSON.stringify('http://localhost:3210'),
      })
    );
  }

  return {
    entry: './src/index.ts',
    mode: 'development',
    devtool: 'inline-source-map',
    devServer: {
      contentBase: './dist',
      hot: true,
    },
    plugins,
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          use: 'awesome-typescript-loader',
          exclude: /node_modules/,
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: ['file-loader'],
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          use: ['file-loader'],
        },
      ],
    },
    resolve: {
      extensions: ['.ts', '.js'],
    },
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
  };
};
```

In order to use the previously declared `SERVICE_URL` in your web app, you still need to declare it (e.g. in `declarations.d.ts`)

```ts
declare var SERVICE_URL: string;
```

As Webpack replaces your `SERVICE_URL` everywhere, complete dead code blocks (`if (false) { ... }`) can be removed during the minification, so that is rather need.

## Other build environments

For React or Vue applications, their build tools do this automatically for you: environment variables that follow a specific naming syntax, e.g. start with `VUE_`, are exposed into your web app.

## REST-EASY-LOKI

I follow a similar approach for a small REST service that I built around the in-memory database, lokijs, [rest-easy-loki](https://www.npmjs.com/package/rest-easy-loki). All environment variables that start with `LOKI_` are exposed at `SERVER/api/env` dynamically.