Implementing Dynamic Environment Configuration in Angular for Avoiding One Build per Environment

Share on facebook
Share on google
Share on twitter
Share on linkedin

One big flaw of the Angular CLI’s way of handling environments, according to the build once, deploy many DevOps principle, is that out-of-the-box Angular CLI wants you to create one separate build per environment.

Why should you only build once and reuse that build in all environments?

The reason why you don’t want to create a separate build for every environment is:

  1. It slows down CI pipelines because it needs to create a build for every environment
  2. It increases the risk of errors/differences in different environments because the builds are separate
  3. It adds unnecessary information about other environments in the code
  4. You might, for security reasons, don’t want to show confidential information in the environment config, which is saved to the version control

All these problems make me wonder why Angular CLI is opting for one build per environment. I sure wanted a solution to these problems.

How are these problems solved?

By making the deployment server substitute a config.json file, which is loaded on runtime by the app.

Making an Angular app use dynamic configurations

We want to make the Angular app only have two environment files: environment.ts and

Why two environments you may ask? One for local dev use, where you can put whatever you want when serving locally and one used when doing a prod build of the app. These environment files are getting most of its values from an app-config.json file loaded on runtime as contrast to having all the environment info hardcoded in the environment files.

Create a new Angular CLI App

The first step is to create a new Angular CLI app by opening the terminal, go to the desired directory for the app and type:

ng new dynamic-config-demo

And this should create a new Angular CLI app for you.

Loading the config.json file on startup

All the environment configuration are gonna be stored in a app-config.json file used by the environment.ts file for referencing these values type-safely.

We simply create an empty JSON file inside the assets folder called app-config.json.

The next step is to load the config.json file using an app.init.ts initialization service:

This service will run on startup and will ensure that the app-configuration is getting fetched by using fetch to get the configuration file and then save it in window for making it globally available to the application. Note, when using fetch you might need polyfills for IE browser support.

The app initializer service is set up in the app.module like this:

Using an app initializer service creates a slight delay on the startup time of the application, but simple stuff like this won’t have a big impact on startup time. Still, I recommend that you let your users know to wait using a loading spinner.

Make the environment files use dynamic values

Now that we are loading the configuration JSON dynamically and saving them in window, we want to be able to reference them type-safely. To do this, we should have three environment files: environment,, and dynamic-environment.

environment is for using locally, is for production and dynamic-environment is shared with environment and for providing dynamic configuration.

dynamic-environment looks like this:

This is used in environment like this:

Now we can try the new dynamic config capabilities out by displaying the environment name like this:

You can find a complete demo of an Angular app with dynamic configuration on my Github here.

Substituting the config.json file on the deployment server

Now that we have set the app up for dynamic configuration the next part is to set up substitution of the config file on the deployment server.

I have done this using Octopus, which has a smart function to substitute a JSON file with configuration values for the environment. Other deployment servers should have similar capabilities to substitute a JSON file right before deploying the app to the front end server.


We discussed the problems with the “Angular CLI” way of handling environment configuration with one build per environment and looked at why it is beneficial to do build once, deploy many instead. We looked at how to implement this using an app.init service which loaded a dynamic configuration file on initialization, with values set by the deployment server.

If you liked this post remember to comment, share and follow me on Twitter.

Do you want to become an Angular architect? Check out Angular Architect Accelerator.

Related Posts and Comments

How to Handle Errors in a Reactive Angular App

In this post, we will cover how to handle errors in a reactive Angular app. To provide a good user experience you should always let your users know what state your application is in. That includes showing a loading spinner when it’s loading and showing error messages if there are any errors. It is a

Read More »

How to Set Up Git Hooks in an Nx Repo

Git hooks can be used to automate tasks in your development workflow. The earlier a bug is discovered, the cheaper it is to fix (and the less impact it has). Therefore it can be helpful to run tasks such as linting, formatting, and tests when you are e.g. committing and pushing your code, so any

Read More »

The Stages of an Angular Architecture with Nx

Long gone are the times when the frontend was just a dumb static website. Frontend apps have gotten increasingly complex since the rise of single-page application frameworks like Angular. It comes with the price of increased complexity and the ever-changing frontend landscape requires you to have an architecture that allows you to scale and adapt

Read More »

The Best Way to Use Signals in Angular Apps

Since Angular 16, Angular now has experimental support for signals and there is a lot of confusion in the community about whether this is going to replace RxJS or how it should be used in an app in combination with RxJS. This blog post sheds some light on what I think is the best way

Read More »

High ROI Testing with Cypress Component Testing

Testing is one of the most struggled topics in Angular development and many developers are either giving up testing altogether or applying inefficient testing practices consuming all their precious time while giving few results in return. This blog post will change all this as we will cover how I overcame these struggles the hard way

Read More »