How Angular applications boot
Published: 2021-03-28 19:21:45

In this article, I'll give you an overview of how Angular applications are bootstrapped. Note that this is an article for beginners, not a deep-dive.

## High-level process

For an Angular application to start, multiple things have to happen within the Web browser:

- The HTML of the entry point must be loaded
- The different JavaScript bundles of the application must be loaded
- The main bundle of the application must be executed
- The main bundle must load Angular and trigger the bootstrap of the root Angular application module
- Angular must bootstrap the root Angular application module, and render the application

Let's look at those steps a bit more in detail.

## HTML entry point

First of all, the `index.html` file is downloaded and evaluated by the Web browser:

{% gist https://gist.github.com/dsebastien/860fbeb464d6d78f185df8ddda535338 %}

At a minimum, the body of that HTML file must contain the _root component_ (i.e., its _entry point_ component); in this case `<app-root></app-root>`. As soon as the Angular application gets loaded and executed, Angular will recognize it and will update the DOM with the interpolated/rendered template.

That's actually the "end" of the story. Let's rewind a bit.

## JS bundles loading

If you open up the `index.html` file in the sources of a brand new Angular application, you won't find any of the scripts that you saw above. Why? Because they're added by the _build process_. When you use the [Angular CLI](https://cli.angular.io), it first reads the `angular.json` file (or `angular-cli.json`) to learn about the project's configuration. Then, based on that, it builds the whole application.

Underneath the covers, the Angular CLI uses [Webpack](https://webpack.js.org), a module bundler. Among other things, Webpack (with the help of many plugins) transforms the project code and assets into JavaScript bundles. Those bundles contain all of the code of the application, as well as the code of third-parties (e.g., Angular, and other libraries that you may use).

When an Angular application is built using `ng build --prod`, there are a few files that are generated under `dist/<application_name>`:

```
├── 3rdpartylicenses.txt
├── favicon.ico
├── index.html
├── main.1feaffbe857aaf7ee0db.js
├── polyfills.a4021de53358bb0fec14.js
├── runtime.e227d1a0e31cbccbf8ec.js
└── styles.09e2c710755c8867a460.css
```

> The seemingly random strings after the bundle names are hashes, added there
  for cache busting. That is, to ensure that Web browser use the updated content
  and not a version that they stored locally before. Normally, if your content
  does not change, then the strings will remain the same even if you build
  multiple times.

We've already discussed the `index.html` file. Let's take a look at the JavaScript files:

- `main.js`: your application code and everything you have imported
- `vendor.js`: third-party code that your application depends on
- `polyfills.js`: polyfills that allow using newer features in older environments (e.g., using Angular on outdated Web browsers)
- `runtime.js`: utility code used by Webpack to load code at runtime

Those JavaScript bundles are generated by Webpack, and added as `<script>` tags in the `index.html` file, as we've seen previously.

Note that you could have additional bundles if you make use of features such as [lazy-loading Angular modules](https://angular.io/guide/lazy-loading-ngmodules).

Since those script tags are part of the `index.html` file, the Web browser will also load these. But loading those is not enough for something to happen. Code must be executed for your application to start. Let's look at that next.

## Main entry point execution

The `main` bundle is the one of interest here. As I've mentioned in the previous section, it's the one containing the code of our Angular application.

That bundle actually contains our whole application code. But what part of it should be executed? Well it is something that is configured in the `angular.json` file:

{% gist https://gist.github.com/dsebastien/c0d0b9e5bde8c436162206d5f94a0b9b %}

The `main` property in the code snippet above (line 19) determines the module should be loaded and executed as soon as the main JavaScript bundle is loaded at runtime.

As you can see above, by default, it is the `main.ts` module. Because of that configuration, the Angular CLI will ensure that the corresponding module gets loaded by Webpack and executed as soon as possible once the bundles are loaded.

Now, you know that the `main.ts` file is the entrypoint for Angular applications, and _why_ it gets loaded & executed. Now let's look at what it does!

## Angular application bootstrap

If you haven't changed anything, then the `main.ts` file should look as follows:

{% gist https://gist.github.com/dsebastien/521f7a468bcb05662d1bac86886eb149 %}

There are multiple things to notice here.

First, there are a number of import statements. Those will remain once the code is transpiled into JavaScript code by the compiler. At runtime, those imports will be taken care of by Webpack. Once the imports have been _executed_, the rest of the code will execute.

Second, if the project has been built for production, then the [production mode of Angular](https://angular.io/api/core/enableProdMode) will be enabled. This is pretty important for performance.

Finally, and most importantly, the following line will be executed:

```
platformBrowserDynamic().bootstrapModule(AppModule);
```

It's a single line, but it does _a lot_. `platformBrowserDynamic` is a module that is able to load Angular in the context of a Web browser. It loads the necessary elements of the framework and configures what needs to be. Given that Angular can run in other contexts (e.g., mobile, server-side, etc), note that there are other ways to load Angular.

So, the first part, `platformBrowserDynamic()` loads Angular. Once that is done, the second part `bootstrapModule(...)` instructs Angular to bootstrap the given module. By default, all Angular applications include _at least_ an `AppModule`.

At this point, Angular takes over, loads the components, services, directives, pipes, and whatever else your `AppModule` may import, refer to, declare, etc. In fine, it will look for a component matching the `app-root` _selector_. Normally, that component is the `AppComponent`:

{% gist https://gist.github.com/dsebastien/91eceb327732bbd42a54f3cbf5a73b30 %}

Once Angular has found that component, it will render it for you and update the DOM of the page include the rendered content.

If you are curious and want to know more, then check out the following articles:

* https://angular.io/guide/bootstrapping#launching-your-app-with-a-root-module
* https://stackoverflow.com/questions/48942691/how-angular-builds-and-runs
* https://medium.com/angular-in-depth/angular-platforms-in-depth-part-2-application-bootstrap-process-8be461b4667e

## Conclusion

In this article, I've briefly explained how Angular applications are bootstrapped. It's not the whole story (I've left all the gory details out), but it should help you have a clearer understanding of the important steps of the process.

That’s it for today!

PS: If you want to learn tons of other cool things about product/software/Web development, then [check out the Dev Concepts series](https://dev-concepts.dev/), [subscribe to my newsletter](https://dsebastien.net/news), and [come say hi on Twitter](https://twitter.com/dSebastien)!