Angular 19 has been released!
Standalone by default
First things first—when you update, make sure to run ng update
or nx migrate
, but avoid using the native npm install
command.
Don’t be surprised if the update script changes all your components. Standalone is now the default.
The update script removes standalone: true
from all components, while NgModule-based components will now have standalone: false
added.
Utility Functions for Signals
linkedSignal()
With linkedSignal
, you can clone an existing Signal. You can modify the clone, but those changes won’t affect the original. However, if the original Signal updates, its value will overwrite the clone.
This is perfect for:
- Template-driven forms, where you need a working copy of a Signal.
Pre Angular 19:
export class CustomerComponent {
// original
customer = input.required<Customer>();
// working copy
formCustomer: Customer | undefined = undefined;
// synchronization
#syncEffect = effect(() => {
this.formCustomer = this.customer();
})
Angular 19:
export class CustomerComponent {
// original
customer = input.required<Customer>();
// working copy
formCustomer = linkedSignal(this.customer)
}
- Managing a state linked to a parent Signal. For example, when a parent component passes down an ID to a child component, and the child’s state needs to reset when the parent’s Signal changes.
Pre Angular 19
export class BasketComponent {
protected readonly selectedProductId = input.required<number>();
protected readonly amount = signal(1);
readonly #resetEffect = effect(
() => {
this.selectedProductId();
this.amount.set(0);
},
{ allowSignalWrites: true },
);
}
Angular 19
export default class BasketComponent {
protected readonly selectedProductId = input.required<number>();
protected readonly amount = linkedSignal({
source: this.selectedProductId,
computation: () => 1,
});
}
linkedSignal
is in developer preview. While the functionality is stable, breaking changes within a major version are still possible.
resource()
& rxResource()
The resource
function addresses Signals where the value comes from an asynchronous task, such as an HTTP request. Its standout feature is managing race conditions by automatically canceling HTTP requests — without using RxJS.
Pre Angular 19
export class EditCustomerComponent {
readonly #customerService = inject(CustomerService);
readonly id = input.required({ transform: numberAttribute });
readonly customer = signal<Customer | undefined>(undefined);
readonly #loadEffect = effect(() => {
this.#customerService.findById(this.id()).subscribe((customer) => {
this.customer.set(customer);
});
});
}
Angular 19
export class EditCustomerComponent {
readonly #customerService = inject(CustomerService);
readonly id = input.required({ transform: numberAttribute });
readonly customer = resource({
request: () => this.id(),
loader: (options) => {
const id = options.request;
return this.#customerService.fetchById(id, options.abortSignal);
},
});
}
Additionally, there’s an RxJS-powered version called rxResource
.
Both functions are still experimental, so breaking changes are likely.
However, this marks a fundamental milestone, showcasing Angular’s direction with Signals and its "optional RxJS" approach.
Incremental Hydration
Incremental Hydration allows parts of your template to hydrate based on specific triggers.
For example:
- When a user interacts with it.
- After a delay.
- Or never
@Component({
selector: 'app-edit',
template: `
<div class="flex">
<div class="flex-1 p-4">
<app-full-text #editor [(content)]="munichDescription" />
</div>
<div class="flex-1 prose p-4 mx-auto">
@defer (hydrate never) {
<!-- Component with heavy dependency to marked library -->
<app-markdown-renderer [markdown]="munichDescription()"/>
}
</div>
</div>`
})
export class EditComponent {}
This feature comes from Angular’s collaboration with Wiz, Google’s internal framework used in Gmail, Google Search, and other performance-intensive applications.
While Incremental Hydration might not be relevant for all use cases — such as internal applications — it opens Angular to a completely new group of developers.
These are developers who previously relied on frameworks like Next.js, Remix, or Qwik to build interactive websites that load instantly and are efficient in terms of bundle size.
More Information
For more information, check out:
The official release video on YouTube.
The Q&A session with Mark and Jeremy from the Angular team.
The Angular blog post
Top comments (1)
Careful for mono repos with multiple projects
There is a language service issue which marks the missing standalone flag as an error. Many people reported it, us included.
Other than that, v19 is an awesome release.