Angular's Huge Comeback
Angular always had a lot going for it. It is maintained by a dedicated team of really talented developers inside Google, and is battle tested in some of the biggest web products out there.
However, the web dev space and expectations changed drastically in recent years due to some breakthroughs in both browser performance and architectural decisions.
As a result, since version 14 the Angular team doubled down on their investment in developer experience and performance.
It all started with standalone components, directives and pipes which removed the dependency on the somewhat cumbersome angular NG modules.
Overview
Then they drastically improved app performance thanks to the newly added fine grained reactivity via signals.
@Component({
selector: 'app-counter',
template: `
<div>
<p>Count: {{ count() }}</p>
<button (click)="increment()">+1</button>
</div>
`
})
export class Counter {
count = signal(0);
increment() {
this.count.set(this.count() + 1);
}
}
These act as a replacement to the slower, harder to debug zone JS based reactivity model.
So you get the point, the Angular team is rapidly deprecating and removing unnecessary components from their product, building a more robust, performant solution.
The performance was also improved on the server thanks to a better rendering experience. This is the result of the Angular team collaborating with the Google team who is in charge of Search. In short, thanks to an approach called Event Replay, user events triggered on components which are not hydrated yet will not be lost. Once the hydration process finishes, the events will be processed.
What’s really exciting to see is Angular’s commitment to the community. The team collaborates closely with Firebase, Netlify, Puppeteer, Playwright and Vite to improve the whole web development experience.
Angular 19 builds on top of all this existing work, and takes the user experience and performance improvements one step further.
1. Default Standalone
First of all, standalone is the new default for all components, directives and pipes. This means you don’t have to explicitly set the standalone flag to true any more.
On top of that, once you update to version 19, you can run the ng update command, which will refactor your code so that all existing entities declared in NG modules will get a standalone false flag.
2. Signals
Second, starting with version 19, more signal based APIs are becoming stable and ready to use.
What’s more interesting though is the addition of a couple of new and experimental signal APIs such as the linked Signal which gives you more control over computed signal based values.
const user = signal({id: 1, name: 'Joe'});
const email = linkedSignal({
source: user,
computation: u => `${u.name}@hi.com`,
equal: (a, b) => a.id === b.id,
});
If you worked with Solid JS in the past, you’ll be really excited about the resource function which lets you work with asynchronous values as part of the Angular signal graph.
const userId: Signal<string> = getUserId();
const userResource = resource({
request: () => ({id: userId()}),
loader: ({request}) => fetchUser(request),
});
const name = computed(
() => userResource.value().name
);
While these changes are great for new projects, one big aspect of the Angular world are the existing codebases. There are a huge number of large projects already shipped to production using older Angular versions.
Automatic Refactoring
While migrating was rather easy in the past thanks to thoroughly documented migration guides, version 19 introduces new automatic refactoring tools to take advantage of signals based reactivity.
The signal input migration will convert inputs using the decorator API to signal based inputs.
ng generate @angular/core:signal-input-migration
Similarly, signal queries migration will convert queries like view child or content child to their signal based equivalents.
ng generate @angular/core:signal-queries-migration
Finally, running output migration will update your code to the new function based output API.
ng generate @angular/core:output-migration
Incremental Hydration
Hydration is a really important step in ensuring good performance for modern web apps, and Angular is focusing on improving this for quite a while. All this work is now allowing the team to introduce a very powerful feature. Incremental hydration allows you to annotate parts of your template, using already familiar @defer syntax, instructing Angular to load and hydrate them on specific triggers, lazily.
@defer (hydrate on idle) {
<large-cmp />
} @placeholder {
<div>Placeholder</div>
}
An exciting consequence of this approach is that your app will require a smaller JS bundle to load and it will be bootstrapped faster. This whole process is deserving of a video on its own, so please let me know in the comments if you are interested in a deep dive into modern hydration.
If you want to find out more about Angular or web dev in general you can check some of the other videos on my channel.
Until next time, thank you for reading!