Angular was known for heavy boilerplate. Angular 19 with signals, standalone components, and new control flow is a completely different framework — modern, fast, and surprisingly pleasant.
What Changed
| Before (Angular 14) | After (Angular 19) |
|---|---|
| NgModules required | Standalone components |
| RxJS for everything | Signals (reactive primitives) |
| Zone.js (monkey-patching) | Zoneless (signal-based change detection) |
| *ngIf, *ngFor directives | @if, @for control flow |
| Heavy boilerplate | Clean, minimal code |
Signals (Reactive State)
import { signal, computed, effect } from "@angular/core";
@Component({
standalone: true,
template: `
<h1>Count: {{ count() }}</h1>
<p>Doubled: {{ doubled() }}</p>
<button (click)="increment()">+1</button>
`,
})
export class CounterComponent {
count = signal(0);
doubled = computed(() => this.count() * 2);
constructor() {
effect(() => {
console.log(`Count changed to ${this.count()}`);
});
}
increment() {
this.count.update(c => c + 1);
}
}
No RxJS. No subscriptions. No memory leaks.
New Control Flow
<!-- Before: structural directives -->
<div *ngIf="user; else loading">
<div *ngFor="let item of items; trackBy: trackById">
{{ item.name }}
</div>
</div>
<!-- After: built-in control flow -->
@if (user) {
@for (item of items; track item.id) {
<div>{{ item.name }}</div>
} @empty {
<p>No items found</p>
}
} @else {
<p>Loading...</p>
}
Standalone Components (No NgModules)
@Component({
standalone: true,
imports: [CommonModule, RouterLink],
template: `
<nav>
<a routerLink="/">Home</a>
<a routerLink="/about">About</a>
</nav>
`,
})
export class NavComponent {}
Resource API (Data Fetching)
import { resource } from "@angular/core";
@Component({
standalone: true,
template: `
@if (users.isLoading()) {
<p>Loading...</p>
} @else {
@for (user of users.value(); track user.id) {
<div>{{ user.name }}</div>
}
}
`,
})
export class UsersComponent {
users = resource({
loader: () => fetch("/api/users").then(r => r.json()),
});
}
Deferrable Views
@defer (on viewport) {
<heavy-chart-component />
} @placeholder {
<div>Chart will load when scrolled into view</div>
} @loading (minimum 500ms) {
<spinner />
}
Lazy-load components based on viewport, interaction, timer, or idle.
SSR (Server-Side Rendering)
ng new my-app --ssr
SSR is now a first-class citizen with hydration support.
Building enterprise web applications? I create developer tools and data infrastructure. Email spinov001@gmail.com or check my Apify tools.
Top comments (0)