Should I upgrade to Angular 16?

Updated: 2023-05-06

How to upgrade and is it worth ?

Would not be nice if it was enough to

ng update 

and everything works? But nooo ... ;-)

you will get a list of packages that require to be upgraded

Using package manager: npm 
Collecting installed dependencies... 
Found 36 dependencies. 
We analyzed your package.json, there are some packages to update: 
Name                                     Version                  Command to update 
-------------------------------------------------------------------------------------- 
@angular-eslint/schematics               15.2.1 -> 16.0.1         ng update @angular-eslint/schematics 
@angular/cdk                             15.2.2 -> 16.0.1         ng update @angular/cdk 
@angular/cli                             15.2.4 -> 16.0.1         ng update @angular/cli 
@angular/core                            15.2.2 -> 16.0.1         ng update @angular/core 
@angular/material                        15.2.2 -> 16.0.1         ng update @angular/material 

this list is not exhaustive, but you can update these dependencies with:

ng update @angular-eslint/schematics or ng update the libraries one by one if something goes wrong.

In the terminal you should see something like:

Fetching dependency metadata from registry... 
Updating package.json with dependency @angular-devkit/build-angular @ "16.0.1" (was "15.2.4")... 
Updating package.json with dependency @angular-eslint/builder @ "16.0.1" (was "15.2.1")... 
Updating package.json with dependency @angular-eslint/eslint-plugin @ "16.0.1" (was "15.2.1")... 
Updating package.json with dependency @angular-eslint/eslint-plugin-template @ "16.0.1" (was "15.2.1")... 
Updating package.json with dependency @angular-eslint/schematics @ "16.0.1" (was "15.2.1")... 
... 

This is just the beginning, if you are using Angular Material you will have to repeat the process with @angular/material and maybe Angular CDK.

Every external dependency will put your migration at risk if the library has not been migrated yet.

We had for example an issue with @angular-material-components/file-input that supports, at the moment, only Angular 15.
Luckily for us was a secondary feature that we could 'suspend'.

Upgrade an existing project to Angular 16, is it worth?

Sure, you will have to update at some point. The question is if you have to put extra effort to anticipate as soon as possible the upgrade or if you can wait because the benefits of the new version are not worth the immediate upgrade.

Here, you find the complete list of changes https://github.com/angular/angular/releases/tag/16.0.0

and here the checkpoint of the migration:

https://update.angular.io/?v=15.0-16.0

In my opinion,based on some clients' projects I am working on, the immediate upgrade of existing projects (already in production with Angular 15) is not worth the extra effort and risks.

If you have projects in development (pre-UAT phase) and enough time before the Production date or if you are creating libraries or using Standalone Components, the immediate migration could be justified and worth a try.

Ivy only could be an issue - Angular View Engine libraries will no longer work

Angular 16 removes the old rendering engine to embrace completely Ivy, this can create issues with external dependencies.

A quote from update.angular.io

Due to removal of the Angular Compatibility Compiler (ngcc) in v16, projects on v16 and later no longer support View Engine libraries.

If in the log of Angular you see the message Encourage the library authors to publish an Ivy distribution, you should probably test very well that the external library works as intended.

We had a similar issue with AzureAD (@azure/msal-angular microsoft-authentication-library-for-js) and after we saw that the ticket was open since 2021 without any serious engagement of Microsoft we changed the Auth approach to avoid issues.

Here the link to the breaking changes with the information about the View Engine.

Should I start a new project with Angular 16?

There are a lot of new features in the Developer Preview that are interesting, but 'ready for prod' the main interest for a migration, in my projects, would be the support to TypeScript 5.

For new projects, you have to evaluate the dependency with external libraries. If these dependencies support Ivy, I would recommend Angular 16 and try out some preview features. If the support for Ivy is not guaranteed ... stick with a previous version until you can.

Angular 16 improvements

Notes from presentations of the Angular Team. Some comments and examples are mine, in particular with references to use cases interesting in my projects. The videos of the Angular Team are great but often they last one or two hours with some not relevant material and it's not too easy to find again some important information.
Here are some nuggets.

Route parameters

Now the component can receive parameters from the route without the need for a service injection

const routes = [{ 
	path: 'client', 
	loadComponent: import('./client'), 
	resolve: { client: () => getClient() } 
}] 

In your component:

@Component({...}) 
export class Client { 
	 @Input() client?: string; 
} 

In this case, the client is automatically filled through the routing function call.
You can pass directly route, query, and path parameters to the component.

Self-closing tags

The custom component now are self-closing:

<app-my-component [my-message]="my-variable"> 
</app-my-component> 

can be shortened with :

<app-my-component [my-message]="my-variable" \> 

Mandatory input fields

According to the Angular team, this was a very popular request, mandatory @input parameters in the input decorator:

@Component({...}) 
export class Customer { 
  @Input({ required: true}) customerCode: string = ''; 
}			 

If customerCode is not passed an error will be thrown. This should reduce the number of runtime errors and improve the quality of the contracts when using external components and libraries.

Content Security Policy: Nonce

Possibility to specify Nonce for the Content security policy:

import {CSP_NONCE} from '@angular/core'; 
... 
 
bootstrapApplication(AppComponent, { 
	providers: [{ 
		provide: CSP_NONCE, 
		useValue: global.myNonceValue 
	}] 
}); 

Content Security Policy (CSP) is a security feature that helps prevent cross-site scripting (XSS) and other code injection attacks by defining a whitelist of trusted sources for content such as scripts, stylesheets, and images.

Signals (developer preview)

In Angular 16 the Angular Team propose a new concept of reactivity.

The goal is to have a more granular, more performant change management compared to the current zone.js.

Signals core concepts

3 reactive primitives:

  • signal: like a variable, it holds a value that can change. When it changes it notifies Angular about the change. e.g.: firstName = signal('Marco');
  • computed: kind of signal that is recomputed if one of its components changes: fullName = computed(()=> firstName() + familyName());
  • effect: functions that execute when one of its components (signals) change: effect(() => console.log('Name changed: ', lastName()));

If signals will be adopted by the developer, this will have to communicate to the DOM the change of variables. With currently this task is done by zone.js which tells the DOM/template that a variable has changed. At first, it seems like to pass from a vehicle with automatic speed to one with manual gears. You can optimise the second, but the first is more comfortable.

zone.js will stay in Angular and if the developer decides to migrate, this path is not yet clear.

The signals can be put everywhere and are not bound to a component. It can be in services, directives whatever, the updated signal can be referenced in multiple components.

Other changes in Angular 16

Many other changes are not detailed here:

  • Improvements for IDE (Language Service in VS code, autocomplete import in templates)
  • New server engine for development Vite (in preview, needs to be enabled). This should improve, among other features, the hot reload and refresh (HMR)
  • ng new generates fewer files, more configuration will be added if required (lazy) and the starting project structure is simplified
  • Injectable and more flexible ngOnDestroy, must look a this!
  • TypeScript 5 is supported, here
    is the list of new features.

Standalone components Update

Standalone API / components were introduced in Angular 15. In version 16 they have been improved.

Improvement in lazy-loading experience

Lazy loading required a lot of boilerplate using modules. With Standalone API the lazy loading has been simplified:

export const routes: Routes = [{ 
	path: 'items', 
	loadChildren: () => import('./items/items.routes') 
}]; 

The RouterModule.forChild , import('module') and the rest of the boilerplate are gone.

Same for lazy-loading components:

export const routes: Routes = [{ 
	path: 'items', 
	loadComponent: () => import('./items/items.component') 
}]; 

Server Side Rendering (SSR, developer preview)

Until now Angular was using a Destructive hydration. This means that the application is rendered on the server side and re-rendered completely in the browser.

Now Angular introduced the support for Full hydration, this is a developer preview in Angular 16:

  • The application is rendered on the server side
  • Angular will try to match and re-use the structure in the browser

Angular is still and remains a reactive framework, there is no goal similar to NextJS to render static pages at build time. It's not a big surprise and for this reason, this blog is not using Angular for the frontend. Angular is ideal for business applications, static websites are a different use case for different technologies.

Angular Material 16

I quickly looked into the release notes and I found mostly fixes, if you are fighting with some annoying bugs you could have interest in the migration.

There are some new features, but they seem minor improvements for my use cases (change icon-button to use MDC's token API, make button ripples lazy, tabs: add stretchTabs to MatTabsConfig).

Question about naming convention

A question from the public was about the naming of the components:

Should I name a Component: 'CustomerComponent' or Customer with Standalone Components ?. The Angular team left the freedom, no strategy is recommended.
I notice that very often the Angular Team has different approaches to the naming convention. In general, you can choose the pattern that better suit your team.

Ideas to deep dive

  • Lazy load components without using the router but using JavaScript ES6 dynamic loading
  • Example of a new App using only Standalone, the participants of the Angular team recommend to start new applications using only Standalone API and to don't mix / use the classical module architecture. To generate a new Standalone API App: ng new your-app-name --standalone
    For a migration: ng generate @angular/core:standalone

Sources

Update Angular to v16 official page

Angular Update Guide https://update.angular.io/

A big thank you to the Angular Team that is creating so much documentation and a true show on YouTube to answer the questions of the community. You can watch the full video (1h19 minutes) here:
https://www.youtube.com/watch?v=sJzCy8pRU5g


You could be interested in

Right click context menu with Angular

Right click custom menu inside dynamic lists with Angular Material
2020-05-31

Enums in Angular templates

How to use enum in the html template
2019-01-21
WebApp built by Marco using SpringBoot 3 and Java 21. App hosted in Switzerland.