Stable Release in branch 19.0
19.2.25
Released 02 Jun 2026
(4 months ago)
SoftwareAngular
Version19.0
Initial release19.0.0
19 Nov 2024
(1 year ago)
Latest release19.2.25
02 Jun 2026
(4 months ago)
Active support end28 May 2025
(Ended 1 year ago)
Security support end19 May 2026
(Ended 4 months ago)
Commercial support
(HeroDevs-NES)
Yes
Release noteshttps://github.com/angular/angular/releases/tag/19.0.0
Source codehttps://github.com/angular/angular/tree/19.2.25
Documentationhttps://angular.dev/overview
Angular 19.0 ReleasesView full list

What Is New in Angular 19

Category Highlights
New Features
  • Experimental linkedSignal() -- a writable, source-aware reactive primitive
  • Experimental resource() and rxResource() APIs for async state management
  • Experimental httpResource() for declarative, signal-driven HTTP requests (v19.2)
  • Experimental Incremental Hydration via withIncrementalHydration() and @defer (hydrate on ...)
  • Experimental Server Route Configuration with per-route RenderMode (SSR / SSG / CSR)
  • Experimental afterRenderEffect() for dependency-tracked post-render side effects
  • @let template variable syntax stabilized (introduced in v18.1)
  • routerOutletData input on RouterOutlet with ROUTER_OUTLET_DATA signal token
  • RouterLink now accepts UrlTree objects directly
  • Global default query params handling strategy via withRouterConfig({ defaultQueryParamsHandling })
  • New initializer helpers: provideAppInitializer(), provideEnvironmentInitializer(), providePlatformInitializer()
  • Playwright support added as an e2e option in Angular CLI
  • Template literal support in Angular HTML templates (v19.2)
  • Resource streaming support via stream option and updated rxResource() (v19.2)
  • defaultValue option for resource() and rxResource() (v19.2)
  • Visual Router graph and signal graph in Angular DevTools (v19.1)
  • HMR for HTML templates (v19.1, CSS HMR was added in v19.0)
  • subPath option for internationalized builds in angular.json (v19.1)
  • SSR automatic redirect to preferred language via Accept-Language header (v19.1)
  • New NgComponentOutlet componentInstance property for accessing dynamically loaded component instances (v19.1)
Improvements
  • standalone: true is now the default for all components, directives, and pipes
  • effect() timing fixed -- effects now run as part of the change detection cycle instead of as microtasks
  • allowSignalWrites flag removed from effect()
  • toSignal() in rxjs-interop now accepts a custom equals function
  • Automatic flush() at the end of fakeAsync() test zones
  • New extended diagnostics: uninvoked functions and unused standalone imports
  • New strictStandalone compiler flag to enforce standalone-only declarations
  • TypeScript 5.5 and 5.6 support in v19.0; TypeScript 5.7 support in v19.1; TypeScript 5.8 support in v19.2
  • isolatedModules support in tsconfig.json for up to 10% faster production builds
  • ng-packagr integrated as @angular/build:ng-packagr builder -- no more dependency on @angular-devkit/build-angular for library projects (v19.1)
  • Angular Language Service supports signal-input migration, signal queries migration, and unused-import diagnostics
  • Compiler now warns on missing structural directive imports, including custom ones (v19.2)
  • Validators.required, minLength, and maxLength now correctly handle Set objects via the size property (v19.2)
  • Automatic removal of unused standalone imports via ng generate @angular/core:cleanup-unused-imports (v19.1)
Breaking Changes
  • standalone: true is now the default -- NgModule-based declarations must explicitly set standalone: false
  • this.foo in templates no longer refers to template context variables; use the variable name directly
  • TypeScript versions below 5.5 are no longer supported
  • effect() execution timing changed -- microtask-based scheduling removed; effects now run during change detection
Deprecations
  • APP_INITIALIZER, ENVIRONMENT_INITIALIZER, and PLATFORM_INITIALIZER tokens superseded by the new provide*Initializer() helper functions
  • Constructor-based injection approach can be migrated to inject() via the ng g @angular/core:inject schematic

What is linkedSignal and how does it differ from computed() in Angular 19?

linkedSignal() is a writable signal whose value is automatically recomputed whenever a source signal changes, but can also be manually overridden -- a behavior that computed() simply cannot provide. It ships as an experimental API in Angular 19.0, and it fills the gap between read-only derived state and fully independent writable state.

In practice, the canonical use case is dependent selection: imagine a list of available options stored in one signal and the currently selected item stored in another. When the option list changes, the selection must be validated against the new list. With computed() you would have a read-only result and no easy way to let the user override it; with a plain signal() you have no automatic reset on source change. linkedSignal() handles both.

protected selectedColorId = linkedSignal<Color[], number | null>({
  source: this.colorOptions,        // reacts to this signal
  computation: (source, previous) => {
    // keep previous selection only if it still exists in the new list
    if (previous?.value) {
      return source.some(c => c.id === previous.value) ? previous.value : null;
    }
    return null;
  }
});

// User can still override the value manually
protected onSelect(id: number): void {
  this.selectedColorId.set(id);
}

Watch out for the interaction with the resource() API: both are designed to work together. If you need the selected item's ID to drive a data fetch, wire linkedSignal directly into the request parameter of resource() for a clean, reactive pipeline with no manual subscriptions.

How does the new resource() API replace RxJS-based data loading in Angular?

The resource() API is Angular's built-in answer for async data fetching integrated with the signals model -- tracking load state, handling errors, preventing race conditions, and exposing everything as signals without writing a single RxJS subscription. It is experimental in 19.0 and expanded significantly in 19.1 and 19.2.

A basic resource wires a request signal to a loader function that returns a Promise. The resource automatically re-executes the loader whenever the request signal changes, and it cancels in-flight requests using the provided AbortSignal:

fruitId = signal('apple-id-1');

fruitDetails = resource({
  request: this.fruitId,
  loader: async ({ request: id, abortSignal }) => {
    const res = await fetch(`/api/fruit/${id}`, { signal: abortSignal });
    return res.json() as Promise<Fruit>;
  }
});

// All exposed as signals
isFruitLoading = this.fruitDetails.isLoading;
fruit          = this.fruitDetails.value;
fruitError     = this.fruitDetails.error;

For teams that prefer to stay in RxJS, rxResource() is the Observable-based counterpart; the loader returns an Observable but all output properties remain signals. In 19.2, two further upgrades landed: a defaultValue option eliminates the initial undefined state, and a new stream option supports streaming resources via a Promise<Signal<T>> return type. Also in 19.2, the experimental httpResource() wraps Angular's HttpClient in the resource model, removing manual http.get() calls entirely:

const userResource = httpResource<User>({
  method: 'GET',
  url: () => `/api/users/${userId()}`,  // re-fetches when userId() changes
});

Most teams will find that httpResource() replaces the typical service + subscribe pattern for read operations. Write operations (POST, PUT, DELETE) still go through HttpClient directly for now.

How does Incremental Hydration work in Angular 19, and when should you use it?

Incremental Hydration lets an Angular SSR application selectively rehydrate parts of the page on demand rather than activating the entire app at once on the client -- reducing the JavaScript work needed before the page becomes interactive. It builds directly on top of the @defer block syntax from Angular 17, which means it has no new primitives to learn.

Enable it once at the application level, then annotate deferrable sections with a hydrate trigger:

// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideClientHydration(
      withIncrementalHydration()
    )
  ]
};

// template
@defer (hydrate on viewport) {
  <app-comments />
}

@defer (hydrate on interaction) {
  <app-chat-widget />
}

@defer (hydrate never) {
  <app-footer />   <!-- stays dehydrated indefinitely -->
}

Supported triggers are: idle, interaction, immediate, timer(ms), hover, viewport, never, and when condition. This matters most for content-heavy pages where large sections below the fold (comments, sidebars, footers) do not need to be interactive on load. Pair this with @defer (on viewport) for deferred rendering and hydrate on viewport for deferred hydration to get maximum control over both download and activation timing.

What breaking changes in Angular 19 require action when upgrading?

Angular 19 has four breaking changes, and the most impactful one is that standalone is now the default. Any component, directive, or pipe that should remain inside an NgModule must now carry an explicit standalone: false flag -- or the compiler will treat it as standalone, which breaks NgModule-based dependency resolution.

Running ng update @angular/core@19 applies an automated migration that handles the flag insertion for existing declarations. The remaining breaking changes are:

  • this.foo in templates -- template context variables are no longer accessible via this.. If your templates contain this.someVar intending to reference a template variable, remove the this. prefix.
  • TypeScript minimum version -- TypeScript 5.4 and older are dropped. Upgrade to at least 5.5 before migrating. TypeScript 5.6 support arrives with 19.0, 5.7 with 19.1, and 5.8 with 19.2.
  • effect() timing -- effects that were previously scheduled as microtasks now run synchronously during the change detection pass. Tests that relied on specific microtask ordering (e.g., fixture.detectChanges() followed by a microtask flush to observe effect output) will need adjustment. The allowSignalWrites option is also gone; signal writes inside effects are now unconditionally allowed.
// Before Angular 19 -- flag was required to write signals inside effect()
effect(() => {
  this.count.set(this.source() * 2);
}, { allowSignalWrites: true });

// Angular 19+ -- flag is gone, writes are allowed by default
effect(() => {
  this.count.set(this.source() * 2);
});

What developer experience improvements shipped across the Angular 19.x branch?

Beyond the headline reactive features, the 19.x branch delivered a steady stream of DX improvements that reduce boilerplate and speed up feedback cycles across the full development workflow.

Schematic migrations

  • ng g @angular/core:inject -- migrates constructor injection to inject() calls across the codebase.
  • ng g @angular/core:route-lazy-loading -- converts direct component references in route configs to dynamic loadComponent() imports.
  • ng g @angular/core:cleanup-unused-imports -- automatically removes unused entries from standalone component imports arrays (v19.1).

Hot Module Replacement

CSS HMR landed in 19.0 and HTML template HMR arrived in 19.1. Style and template edits now refresh only the affected component in the browser without losing application state -- no full page reload required. This is enabled by default on the dev server.

Compiler diagnostics

Two new extended diagnostics are active in 19.0: uninvoked functions catches cases like (click)="handleClick" where the missing () means the function is never actually called; unused standalone imports flags entries in the imports array that are never referenced in the template. Both surface as compile-time warnings in the IDE via Angular Language Service and as build-time errors when the strictTemplates flag is set.

fakeAsync cleanup

In 19.0, fakeAsync() zones now automatically call flush() at the end of a test, eliminating the manual cleanup step and the cryptic "X timer(s) still in queue" error that previously bit developers who forgot to drain periodic timers.

Template literals in templates (v19.2)

Angular 19.2 adds support for untagged template literals inside Angular HTML templates. String concatenation patterns like {{ 'Hello, ' + name + '!' }} can now be written as {{ `Hello, ${name}!` }} for significantly better readability.

Initializer helpers

The verbose { provide: APP_INITIALIZER, useFactory: ..., multi: true } pattern is replaced by provideAppInitializer(() => { ... }). Equivalent helpers exist for environment and platform initializers. A migration schematic handles the conversion automatically.

Frequently Asked Questions about Angular 19

Is standalone: true the default in Angular 19, and how does ng update handle existing NgModule-based projects?
Yes, standalone is now the default for all components, directives, and pipes in Angular 19. Running ng update @angular/core@19 applies an automatic migration that inserts standalone: false on every declaration that is currently registered in an NgModule, so existing projects continue to compile without manual changes.

What replaced the APP_INITIALIZER token in Angular 19?
Angular 19 introduced provideAppInitializer(), provideEnvironmentInitializer(), and providePlatformInitializer() as cleaner alternatives. They accept a factory function directly without the verbose multi-provider boilerplate. A schematic at ng g @angular/core:app-initializer handles migration automatically.

Does Angular 19 still support RxJS-based data loading or is resource() a replacement?
RxJS-based loading is fully supported. The resource() and rxResource() APIs are additive alternatives -- rxResource() in particular accepts an Observable loader and exposes signal outputs, so teams can adopt signals incrementally while keeping existing HttpClient and RxJS pipelines untouched.

How does the new effect() timing change affect unit tests in Angular 19?
Effects now execute during the change detection pass rather than as microtasks, which means tests that previously relied on Promise.resolve() or flushMicrotasks() to observe effect output may need an additional fixture.detectChanges() call. Tests using fakeAsync benefit from the new automatic flush() at test teardown, which removes the need to manually call discardPeriodicTasks().

What TypeScript versions are supported across the Angular 19 branch?
Angular 19.0 supports TypeScript 5.5 and 5.6; Angular 19.1 adds TypeScript 5.7 support; Angular 19.2 adds TypeScript 5.8 support. TypeScript versions below 5.5 are no longer supported anywhere in the 19.x branch.

Can I enable Incremental Hydration alongside existing defer blocks in an Angular 19 SSR app?
Yes. Incremental Hydration is built on top of the existing defer block infrastructure. You add withIncrementalHydration() to provideClientHydration() in your app config, then add a hydrate trigger to any existing defer block -- for example @defer (hydrate on viewport) -- without changing any other part of the block. Components without a hydrate trigger continue to hydrate using the default full-app hydration strategy.

Releases In Branch 19.0

VersionRelease date
19.2.2502 Jun 2026
(4 months ago)
19.2.2428 May 2026
(4 months ago)
19.2.2327 May 2026
(4 months ago)
19.2.2212 May 2026
(5 months ago)
19.2.2115 Apr 2026
(6 months ago)
19.2.2012 Mar 2026
(7 months ago)
19.2.1925 Feb 2026
(7 months ago)
19.2.1807 Jan 2026
(9 months ago)
19.2.1701 Dec 2025
(10 months ago)
19.2.1626 Nov 2025
(10 months ago)
19.2.1510 Sep 2025
(1 year ago)
19.2.1428 May 2025
(1 year ago)
19.2.1323 May 2025
(1 year ago)
19.2.1221 May 2025
(1 year ago)
19.2.1115 May 2025
(1 year ago)
19.2.1007 May 2025
(1 year ago)
19.2.930 Apr 2025
(1 year ago)
19.2.823 Apr 2025
(1 year ago)
19.2.716 Apr 2025
(1 year ago)
19.2.609 Apr 2025
(1 year ago)
19.2.502 Apr 2025
(1 year ago)
19.2.427 Mar 2025
(1 year ago)
19.2.319 Mar 2025
(1 year ago)
19.2.212 Mar 2025
(1 year ago)
19.2.105 Mar 2025
(1 year ago)
19.1.826 Feb 2025
(1 year ago)
19.2.026 Feb 2025
(1 year ago)
19.1.719 Feb 2025
(1 year ago)
19.2.0-rc.019 Feb 2025
(1 year ago)
19.2.0-next.313 Feb 2025
(1 year ago)
19.1.612 Feb 2025
(1 year ago)
19.1.506 Feb 2025
(1 year ago)
19.2.0-next.206 Feb 2025
(1 year ago)
19.1.429 Jan 2025
(1 year ago)
19.2.0-next.129 Jan 2025
(1 year ago)
19.1.322 Jan 2025
(1 year ago)
19.2.0-next.022 Jan 2025
(1 year ago)
19.1.220 Jan 2025
(1 year ago)
19.1.116 Jan 2025
(1 year ago)
19.0.715 Jan 2025
(1 year ago)
19.1.015 Jan 2025
(1 year ago)
19.0.608 Jan 2025
(1 year ago)
19.1.0-rc.008 Jan 2025
(1 year ago)
19.0.518 Dec 2024
(1 year ago)
19.1.0-next.418 Dec 2024
(1 year ago)
19.0.412 Dec 2024
(1 year ago)
19.1.0-next.312 Dec 2024
(1 year ago)
19.0.204 Dec 2024
(1 year ago)
19.1.0-next.104 Dec 2024
(1 year ago)
19.0.304 Dec 2024
(1 year ago)
19.1.0-next.204 Dec 2024
(1 year ago)
19.0.126 Nov 2024
(1 year ago)
19.1.0-next.026 Nov 2024
(1 year ago)
19.0.019 Nov 2024
(1 year ago)
19.0.0-rc.315 Nov 2024
(1 year ago)
19.0.0-rc.214 Nov 2024
(1 year ago)
19.0.0-rc.106 Nov 2024
(1 year ago)
19.0.0-rc.030 Oct 2024
(1 year ago)
19.0.0-next.1123 Oct 2024
(1 year ago)
19.0.0-next.1016 Oct 2024
(1 year ago)
19.0.0-next.910 Oct 2024
(2 years ago)
19.0.0-next.802 Oct 2024
(2 years ago)
19.0.0-next.725 Sep 2024
(2 years ago)
19.0.0-next.618 Sep 2024
(2 years ago)
19.0.0-next.511 Sep 2024
(2 years ago)
19.0.0-next.409 Sep 2024
(2 years ago)
19.0.0-next.304 Sep 2024
(2 years ago)
19.0.0-next.228 Aug 2024
(2 years ago)
19.0.0-next.122 Aug 2024
(2 years ago)
19.0.0-next.014 Aug 2024
(2 years ago)