What Is New in Angular 16.0
Angular 16 delivers a significant update focused on reactivity, server-side rendering, and tooling. The introduction of a new reactivity model and hydration unlocks major performance gains.
| Category | Key Updates |
|---|---|
| New Features | Signals, Server-Side Rendering Hydration, Required Inputs, Router Inputs, ESBuild Dev Server |
| Improvements | Faster Dev Server, Improved Unit Testing, Better Stack Traces, CLI Autocompletion |
| Deprecations | Angular Elements with Ivy, `RouterOutlet` properties |
How does the new reactivity model work?
The core of Angular 16's reactivity is a new primitive called a Signal. A Signal is a wrapper around a value that notifies consumers when that value changes. You create one with the `signal` function.
count = signal(0);
name = signal('Angular');
To react to Signal changes, you use computed values and effects. This granular tracking allows the framework to optimize updates and minimize unnecessary change detection cycles.
What is hydration and why is it a big deal?
Hydration is the process of attaching event listeners and application state to existing DOM structures rendered by the server. Previously, Angular would completely re-render the client-side app, discarding the server-rendered HTML.
With non-destructive hydration enabled, Angular reuses these server-side nodes. This eliminates content flicker and dramatically improves Core Web Vitals like Largest Contentful Paint (LCP), providing a faster user experience.
Can I make component inputs required now?
Yes, this is a long-awaited feature. You can now mark an input as required by using the `required` option in the input decorator or in the `@Component` metadata. The compiler will throw an error if a parent component doesn't provide it.
@Input({ required: true }) title!: string;
// or in metadata
@Component({
inputs: [{name: 'title', required: true}]
})
How does the router work with component inputs?
The router can now bind route data (like parameters and resolved data) directly to component inputs. This removes the need to inject the `ActivatedRoute` and manually subscribe to observables in your components.
// In your routing configuration
{
path: 'user/:id',
component: UserDetailComponent,
resolve: { user: userResolver }
}
// In your component
@Input() id!: string;
@Input() user!: User;
This makes components cleaner, more declarative, and easier to test in isolation.
What tooling improvements should I try first?
First, check out the new Angular CLI ESBuild-based dev server. It delivers significantly faster build and rebuild times, making your local development loop much quicker.
Secondly, enable the improved unit testing experience. The `TestBed` now runs faster and the new `provideZoneChangeDetection` method allows for more flexible testing without the full Zone.js environment.
FAQ
Are Signals a replacement for RxJS?
No, they are complementary. Signals are great for granular, synchronous state changes within components. RxJS remains the superior choice for managing complex asynchronous event streams and composition.
Is the new reactivity model mandatory?
No, it's entirely optional. The traditional Zone.js-based change detection is still fully supported and is not deprecated. You can adopt Signals incrementally.
How do I enable hydration?
You enable it by adding `provideClientHydration()` to your app's root provider list in `app.config.ts`. This is a prerequisite for using Angular Universal with hydration.
What happens if I use a required input without providing a value?
The framework will throw a compile-time error, catching the bug before your application even runs. This is a major improvement over the previous runtime-only checks.
Why was the ESBuild dev server moved from developer preview?
It's now considered stable and reliable for general use after extensive testing. The performance gains are significant enough to make it the recommended option for local development.