Angular Update Guide

Keeping your Angular application current is essential for unlocking the newest capabilities, performance gains, critical security fixes, and error resolutions. The following is a detailed log I created while upgrading my [portfolio site](https://muhammadawaisshaikh.vercel.app/), which was initially started with Angular 18.2, to Angular 19. This major release brings a host of noteworthy improvements: standalone components now being the default, incremental hydration, TypeScript 5.6 support, signal-based input/output, and updated Material theming. This record details my observations and takeaways from that process.

Using the official update guide makes the transition smooth, giving you direct access to v19.0 and its modern feature set.

Update guide β€’ Angular

The web development framework for building modern apps.

favicon angular.dev

Update Angular Core and CLI

Launch your terminal and switch to the root folder of your Angular project.
To move both Angular Core and the CLI to v19.0, execute this command:

ng update @angular/core@19 @angular/cli@19

This action upgrades your dependencies and triggers any required automated migrations.

Address Standalone Components, Directives, and Pipes

In v19.0, components, directives, and pipes are standalone by default.

@Component({
  selector: 'app-example',
  standalone: false, // Remove this line
  template: `...`
})
export class ExampleComponent {}

For any declarations that remain attached to an NgModule, you must explicitly mark them with standalone: false in their decorators.

@Component({
  selector: 'app-example',
  standalone: false, // Add this line
  template: `...`
})
export class ExampleComponent {}

The Angular CLI handles the code adjustments for this automatically as part of the migration process.

Replace BrowserModule.withServerTransition()

Where your app previously relied on BrowserModule.withServerTransition(), inject the APP_ID token instead.

// Before
import { BrowserModule } from '@angular/platform-browser';
BrowserModule.withServerTransition({ appId: 'your-app-id' });

// After
import { APP_ID } from '@angular/core';
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideClientHydration } from '@angular/platform-browser';

export const appConfig: ApplicationConfig = {
  providers: [
    { provide: APP_ID, useValue: 'your-app-id' },
    provideClientHydration(),
    ...
  ]
};

Upgrade TypeScript

Angular v19.0 now expects TypeScript version 5.5 or higher.
To adjust your TypeScript setup, run:

npm install typescript@5.5 --save-dev

Double-check that your tsconfig.json is set up to work correctly with the new TypeScript version.

Migrate Router Error Handling

The old Router.errorHandler approach should be updated to use withNavigationErrorHandler when working with provideRouter, or errorHandler if you are using RouterModule.forRoot.

// Before
import { Router } from '@angular/router';
constructor(private router: Router) {
  this.router.errorHandler = (error) => {
    console.error('Navigation error:', error);
  };
}

// After (using provideRouter)
import { provideRouter, withNavigationErrorHandler } from '@angular/router';
bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes, withNavigationErrorHandler((error) => {
      console.error('Navigation error:', error);
    }))
  ]
});

// After (using RouterModule.forRoot)
import { RouterModule } from '@angular/router';
@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      errorHandler: (error) => {
        console.error('Navigation error:', error);
      }
    })
  ]
})
export class AppModule {}

Migration to Signal Inputs

This section walks through transitioning from the standard @Input decorator to the signal-based input() function that Angular v19.0 introduces.

ng generate @angular/core:signal-input-migration

Before Migration

Below is the initial implementation using @Input:

import { Component, Input } from '@angular/core';

@Component({
  template: `Recipe: {{ recipe?? '' }}`
})
export class MyComponent {
  @Input() recipe: string | undefined = undefined;
  ...
}

Post-Migration Code

After the transition, here's how the component looks when leveraging the input() function:

import { Component, input } from '@angular/core';

@Component({
  template: `Name: {{ name() ?? '' }}`
})
export class MyComponent {
  readonly name = input<string>();
  ...
}
Enter fullscreen mode Exit fullscreen mode

Addressing Sass Deprecation Warnings in Angular v19

When moving an existing application to the Angular v19 release candidate via the CLI, you'll likely encounter a flood of deprecation warnings emitted by the Sass compiler during build or serve operations.

The terminal output might look similar to this:

Sass Deprecation Warnings β€” Angular v.19

The solution involves adding a specific configuration block to your angular.json fileβ€”or project.json for those using an Nx monorepo:

"architect": {
  "build": {
    "options": {
      "stylePreprocessorOptions": {
        "sass": {
          "silenceDeprecations": ["mixed-decls", "color-functions", "global-builtin", "import"]
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Applying this adjustment should eliminate the newly surfaced deprecation warnings.

remove all the scss import deprecation warnings after v 19 angular update

Resolving the 'imports' Standalone Component Error

imports is only valid on a component that is standalone

This warning appears when the imports property is set on a component that lacks the standalone designation. In Angular v19, the standalone flag is no longer required as all components are standalone by default. Yet, the error falsely suggests that the import: [] array is only permissible when standalone: true is explicitly declaredβ€”which is misleading.

To clear this up, try the following:

  • Uninstall and then reinstall the Angular Language Service extension in VSCode to refresh it.

Reinstall and Refresh the Angular Language Service extension

Refreshing Third-Party Dependencies

It's possible that certain external libraries haven't released versions compatible with Angular 19 yet. To identify any outdated packages in your setup, execute this command:

npm outdated
Enter fullscreen mode Exit fullscreen mode

After upgrading, it's crucial to test your application comprehensively to confirm everything works as expected with Angular 19. Should problems arise, consult the package's documentation or its GitHub repository for patches or alternative solutions.

Removing Redundant Imports

Starting with Angular 19, the framework will now alert you if the imports array of a component contains symbols that aren't referenced in its template. This feature promotes cleaner and more efficient code.

ng generate @angular/core:cleanup-unused-imports
Enter fullscreen mode Exit fullscreen mode

GitHub Pull Request for v19 Upgrade

GitHub logo Migrate/v19 #4

  • Migrated to v.19: (@angular/core@19, @angular/cli@19)
  • Applied Signal Input Migration: @angular/core:signal-input-migration
  • Fixed Sass deprecation warnings
  • Cleaned up unused imports with: (@angular/core:cleanup-unused-imports)

Summary

Making the leap to Angular 19 brings substantial advantages such as better performance, more efficient server-side rendering (SSR) hydration, and compatibility with TypeScript 5.6. Adhering to this detailed guide will help you navigate the upgrade smoothly and leverage all the newest capabilities and improvements. πŸš€