Skip to content

The @nx/angular plugin provides various migrations to help you migrate to newer versions of angular projects within your Nx workspace. Below is a complete reference for all available migrations.

Version: 22.4.0-beta.4

The following packages will be updated:

NameVersionAlways add to package.json
@angular/cli~21.1.0Updated only
@angular-devkit/build-angular~21.1.0Updated only
@angular-devkit/core~21.1.0Updated only
@angular-devkit/schematics~21.1.0Updated only
@angular/build~21.1.0Updated only
@angular/pwa~21.1.0Updated only
@angular/ssr~21.1.0Updated only
@schematics/angular~21.1.0Updated only
@angular-devkit/architect~0.2101.0Updated only
@angular-devkit/build-webpack~0.2101.0Updated only
@angular/core~21.1.0Added if not installed
@angular/material~21.1.0Updated only
@angular/cdk~21.1.0Updated only
@angular/google-maps~21.1.0Updated only
ng-packagr~21.1.0Updated only

Version: 22.3.0-beta.0

Updates webpack-based SSR configuration to use preserve module format and bundler module resolution.

NameVersion
@angular/core>=21.0.0

Updates the TypeScript configuration and import syntax for webpack-based server-side rendering (SSR) projects. This migration sets module: "preserve" and moduleResolution: "bundler" in tsconfig.server.json to align with Angular’s build requirements, and updates server file imports from namespace imports (import * as express) to default imports (import express) to work correctly with the new module format.

For webpack-based SSR projects (using @nx/angular:webpack-server or @angular-devkit/build-angular:server), the migration updates the tsconfig.server.json file:

apps/my-app/tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"target": "es2022",
"module": "commonjs",
"moduleResolution": "node",
"types": ["node"],
},
"files": ["src/main.server.ts", "src/server.ts"],
}
apps/my-app/tsconfig.server.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"target": "es2022",
"module": "preserve",
"moduleResolution": "bundler",
"types": ["node"],
},
"files": ["src/main.server.ts", "src/server.ts"],
}

The migration also updates import statements in the server.ts file to use default imports instead of namespace imports:

apps/my-app/src/server.ts
import * as express from 'express';
import * as compression from 'compression';
import * as cors from 'cors';
const app = express();
app.use(compression());
app.use(cors());
apps/my-app/src/server.ts
import express from 'express';
import compression from 'compression';
import cors from 'cors';
const app = express();
app.use(compression());
app.use(cors());

Projects that already have the correct TypeScript configuration or projects without a tsconfig.server.json file are not modified by this migration.

Version: 22.3.0-beta.0

Update ‘module’ to ‘preserve’ and ‘moduleResolution’ to ‘bundler’ in TypeScript configurations for Angular projects.

NameVersion
@angular/core>=21.0.0-rc.3

Update module to preserve and moduleResolution to bundler in TypeScript configurations

Section titled “Update module to preserve and moduleResolution to bundler in TypeScript configurations”

Updates the TypeScript module and moduleResolution compiler options to 'preserve' and 'bundler' respectively for Angular projects. These settings are required for Angular’s build system to work correctly with modern module resolution algorithms used by bundlers like Webpack, Vite, and esbuild.

The migration updates TypeScript configuration files in Angular projects to set both compiler options:

apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"module": "es2020",
"moduleResolution": "node",
},
}
apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"module": "preserve",
"moduleResolution": "bundler",
},
}

If both values are already set correctly and inherited from an extended tsconfig file, the migration will not modify the configuration:

apps/my-app/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "preserve",
"moduleResolution": "bundler",
},
}
apps/my-app/tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [],
},
}
apps/my-app/tsconfig.json
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "preserve",
"moduleResolution": "bundler",
},
}
apps/my-app/tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [],
},
}

The migration only processes TypeScript configuration files that are referenced by Angular project build targets, ensuring that only Angular-specific configurations are updated.

Version: 22.3.0-beta.0

Updates the ‘lib’ property in tsconfig files to use ‘es2022’ or a more modern version.

NameVersion
@angular/core>=21.0.0

Update TypeScript lib compiler option to ES2022

Section titled “Update TypeScript lib compiler option to ES2022”

Updates the TypeScript lib compiler option in Angular projects to ensure compatibility with Angular v21+, which requires ES2022 as the minimum ECMAScript version. The migration upgrades any ES versions older than ES2022 (such as ES2015, ES2020, etc.) to ES2022 while preserving other library entries like 'dom', 'webworker', etc.

The migration processes TypeScript configuration files referenced by Angular project build targets and updates the lib compiler option when outdated ES versions are detected:

apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2020", "dom"],
},
}
apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["dom", "es2022"],
},
}

When the lib array contains only an ES version older than ES2022 without additional entries, it is upgraded:

apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2020"],
},
}
apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2022"],
},
}

If the configuration already uses ES2022 or higher (e.g., 'es2023', 'esnext'), no changes are made:

apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2022", "dom"],
},
}
apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2022", "dom"],
},
}

When the lib array contains multiple library entries, only the ES version is upgraded while all other entries are preserved:

apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["es2020", "dom", "webworker"],
},
}
apps/my-app/tsconfig.app.json
{
"compilerOptions": {
"lib": ["dom", "webworker", "es2022"],
},
}

The migration only processes TypeScript configuration files that are referenced by Angular project build targets, ensuring that only Angular-specific configurations are updated.

Version: 22.3.0-beta.0

Update ‘vitest’ unit test runner option to ‘vitest-analog’ in generator defaults.

NameVersion
@angular/core>=21.0.0

Update vitest unit test runner option to vitest-analog in generator defaults

Section titled “Update vitest unit test runner option to vitest-analog in generator defaults”

Updates the unitTestRunner generator default from vitest to vitest-analog in nx.json. The vitest option has been split into two explicit options: vitest-angular (uses @angular/build:unit-test) and vitest-analog (uses AnalogJS-based setup).

The migration updates generator defaults in nx.json:

nx.json
{
"generators": {
"@nx/angular:application": {
"unitTestRunner": "vitest",
},
},
}
nx.json
{
"generators": {
"@nx/angular:application": {
"unitTestRunner": "vitest-analog",
},
},
}

Version: 22.3.0-beta.3

Set ‘isolatedModules’ to ‘true’ in TypeScript test configurations for Angular projects.

NameVersion
@angular/core>=21.0.0

Set isolatedModules to true in TypeScript test configurations

Section titled “Set isolatedModules to true in TypeScript test configurations”

Sets the TypeScript isolatedModules compiler option to true in tsconfig.spec.json files for Angular projects using the Jest test runner.

The migration updates TypeScript test configuration files in Angular projects using the Jest test runner to set the isolatedModules compiler option:

apps/my-app/tsconfig.spec.json
{
"compilerOptions": {
"outDir": "./out-tsc/spec",
},
}
apps/my-app/tsconfig.spec.json
{
"compilerOptions": {
"outDir": "./out-tsc/spec",
"isolatedModules": true,
},
}

If the value is already set to true or inherited from an extended tsconfig file, the migration will not modify the configuration:

tsconfig.json
{
"compilerOptions": {
"isolatedModules": true,
},
}
apps/my-app/tsconfig.spec.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
},
}
tsconfig.json
{
"compilerOptions": {
"isolatedModules": true,
},
}
apps/my-app/tsconfig.spec.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
},
}

The migration only processes TypeScript test configuration files (tsconfig.spec.json or custom test tsconfig files referenced by @nx/jest:jest tasks) in Angular projects.

Version: 22.3.0-beta.3

Replace ‘jest-preset-angular/setup-jest’ imports with the new ‘setupZoneTestEnv’ function.

NameVersion
@angular/core>=21.0.0

Replaces the removed jest-preset-angular/setup-jest import with the new setupZoneTestEnv function from jest-preset-angular/setup-env/zone.

Starting with jest-preset-angular v15, the setup-jest files have been removed and replaced with explicit setup functions. The old setup-jest import only supported zone-based testing (zoneless support was added in v14.3.0 with the new setupZonelessTestEnv function), so all projects using the removed import are migrated to use setupZoneTestEnv.

apps/my-app/src/test-setup.ts
import 'jest-preset-angular/setup-jest';
apps/my-app/src/test-setup.ts
import { setupZoneTestEnv } from 'jest-preset-angular/setup-env/zone';
setupZoneTestEnv();

Version: 22.3.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@angular/cli~21.0.0Updated only
@angular-devkit/build-angular~21.0.0Updated only
@angular-devkit/core~21.0.0Updated only
@angular-devkit/schematics~21.0.0Updated only
@angular/build~21.0.0Updated only
@angular/pwa~21.0.0Updated only
@angular/ssr~21.0.0Updated only
@schematics/angular~21.0.0Updated only
@angular-devkit/architect~0.2100.0Updated only
@angular-devkit/build-webpack~0.2100.0Updated only
@angular/core~21.0.0Added if not installed
@angular/material~21.0.0Updated only
@angular/cdk~21.0.0Updated only
@angular/google-maps~21.0.0Updated only
ng-packagr~21.0.0Updated only
zone.js~0.16.0Updated only

Version: 22.3.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^21.0.1Updated only
@angular-eslint/eslint-plugin^21.0.1Updated only
@angular-eslint/eslint-plugin-template^21.0.1Updated only
@angular-eslint/template-parser^21.0.1Updated only
@angular-eslint/utils^21.0.1Updated only
@angular-eslint/schematics^21.0.1Updated only
@angular-eslint/test-utils^21.0.1Updated only
@angular-eslint/builder^21.0.1Updated only
@angular-eslint/bundled-angular-compiler^21.0.1Updated only

Version: 22.3.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin^21.0.1Updated only
@angular-eslint/eslint-plugin-template^21.0.1Updated only
@angular-eslint/template-parser^21.0.1Updated only
@angular-eslint/utils^21.0.1Updated only
@angular-eslint/schematics^21.0.1Updated only
@angular-eslint/test-utils^21.0.1Updated only
@angular-eslint/builder^21.0.1Updated only
@angular-eslint/bundled-angular-compiler^21.0.1Updated only

Version: 22.3.2-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^21.0.0Updated only

Version: 22.2.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@module-federation/enhanced^0.21.2Updated only
@module-federation/runtime^0.21.2Updated only
@module-federation/sdk^0.21.2Updated only
@module-federation/node^2.7.21Updated only

Version: 21.6.1-beta.2

Update the @angular/cli package version to ~20.3.0.

NameVersion
@angular/core>=20.3.0

Update the @angular/cli package version in the package.json file at the workspace root to ~20.3.0.

package.json
{
"devDependencies": {
"@angular/cli": "~20.2.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~20.3.0"
}
}

Version: 21.6.1-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~20.3.0Updated only
@angular-devkit/core~20.3.0Updated only
@angular-devkit/schematics~20.3.0Updated only
@angular/build~20.3.0Updated only
@angular/pwa~20.3.0Updated only
@angular/ssr~20.3.0Updated only
@schematics/angular~20.3.0Updated only
@angular-devkit/architect~0.2003.0Updated only
@angular-devkit/build-webpack~0.2003.0Updated only
@angular/core~20.3.0Added if not installed
@angular/material~20.2.3Updated only
@angular/cdk~20.2.3Updated only
@angular/google-maps~20.2.3Updated only
ng-packagr~20.3.0Updated only

Version: 21.6.1-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^20.3.0Updated only
@angular-eslint/eslint-plugin^20.3.0Updated only
@angular-eslint/eslint-plugin-template^20.3.0Updated only
@angular-eslint/template-parser^20.3.0Updated only
@angular-eslint/utils^20.3.0Updated only
@angular-eslint/schematics^20.3.0Updated only
@angular-eslint/test-utils^20.3.0Updated only
@angular-eslint/builder^20.3.0Updated only
@angular-eslint/bundled-angular-compiler^20.3.0Updated only

Version: 21.6.1-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin^20.3.0Updated only
@angular-eslint/eslint-plugin-template^20.3.0Updated only
@angular-eslint/template-parser^20.3.0Updated only
@angular-eslint/utils^20.3.0Updated only
@angular-eslint/schematics^20.3.0Updated only
@angular-eslint/test-utils^20.3.0Updated only
@angular-eslint/builder^20.3.0Updated only
@angular-eslint/bundled-angular-compiler^20.3.0Updated only

Version: 21.5.0-beta.0

Set the ‘tsConfig’ option to build and test targets to help with Angular migration issues.

Set tsConfig option for build and test targets

Section titled “Set tsConfig option for build and test targets”
  • Set the tsConfig option in the target options for library build executors. It moves the value from the target development configuration and it doesn’t set it if the option is already set.
  • Set tsconfig.spec.json as the tsConfig option in the target options for the @nx/jest:jest executor. It only does it if the file exists and the options is not already set.

The migration will move the tsConfig option for library build executors (@nx/angular:ng-packagr-lite and @nx/angular:package) from the development configuration to the target options if it’s not already set:

libs/lib1/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"configurations": {
"development": {
"tsConfig": "libs/lib1/tsconfig.lib.dev.json"
}
}
}
}
}
libs/lib1/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"options": {
"tsConfig": "libs/lib1/tsconfig.lib.dev.json"
},
"configurations": {
"development": {}
}
}
}
}

The migration will set the tsConfig option for the @nx/jest:jest executor when the tsconfig.spec.json file exists and the option is not already set:

apps/app1/project.json
{
"targets": {
"test": {
"executor": "@nx/jest:jest"
}
}
}
apps/app1/project.json
{
"targets": {
"test": {
"executor": "@nx/jest:jest",
"options": {
"tsConfig": "apps/app1/tsconfig.spec.json"
}
}
}
}

If the tsConfig option is already set in the target options, the migration will not modify the configuration:

libs/lib1/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"options": {
"tsConfig": "libs/lib1/tsconfig.lib.json"
},
"configurations": {
"development": {
"tsConfig": "libs/lib1/tsconfig.lib.dev.json"
}
}
}
}
}
libs/lib1/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"options": {
"tsConfig": "libs/lib1/tsconfig.lib.json"
},
"configurations": {
"development": {
"tsConfig": "libs/lib1/tsconfig.lib.dev.json"
}
}
}
}
}

Version: 21.5.0-beta.2

Update the @angular/cli package version to ~20.2.0.

NameVersion
@angular/core>=20.2.0

Update the @angular/cli package version in the package.json file at the workspace root to ~20.2.0.

package.json
{
"devDependencies": {
"@angular/cli": "~20.1.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~20.2.0"
}
}

Version: 21.5.0-beta.2

Remove any Karma configuration files that only contain the default content. The default configuration is automatically available without a specific project configurationfile.

NameVersion
@angular/core>=20.2.0

Remove the Default Karma Configuration Files

Section titled “Remove the Default Karma Configuration Files”

Removes Karma configuration files that match the default configuration generated by Angular CLI to reduce boilerplate code in the workspace. The migration also removes the karmaConfig option from project targets when the configuration file is removed.

The migration will remove karma.conf.js files that contain only default settings and update the project configuration:

apps/my-app/karma.conf.js
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma'),
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
},
},
jasmineHtmlReporter: {
suppressAll: true, // removes the duplicated traces
},
coverageReporter: {
dir: require('path').join(__dirname, '../../coverage/my-app'),
subdir: '.',
reporters: [{ type: 'html' }, { type: 'text-summary' }],
},
reporters: ['progress', 'kjhtml'],
browsers: ['Chrome'],
restartOnFileChange: true,
});
};
apps/my-app/project.json
{
"name": "my-app",
"targets": {
"test": {
"executor": "@angular-devkit/build-angular:karma",
"options": {
"karmaConfig": "apps/my-app/karma.conf.js",
"polyfills": ["zone.js", "zone.js/testing"]
}
}
}
}

File apps/my-app/karma.conf.js is removed.

apps/my-app/project.json
{
"name": "my-app",
"targets": {
"test": {
"executor": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": ["zone.js", "zone.js/testing"]
}
}
}
}

If the Karma configuration contains customizations, the migration will preserve the file and configuration:

apps/custom-app/karma.conf.js
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma'),
],
browsers: ['ChromeHeadless'], // Custom browser configuration
restartOnFileChange: true,
});
};
apps/custom-app/karma.conf.js
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage'),
require('@angular-devkit/build-angular/plugins/karma'),
],
browsers: ['ChromeHeadless'], // Custom browser configuration
restartOnFileChange: true,
});
};

Version: 21.5.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~20.2.0Updated only
@angular-devkit/core~20.2.0Updated only
@angular-devkit/schematics~20.2.0Updated only
@angular/build~20.2.0Updated only
@angular/pwa~20.2.0Updated only
@angular/ssr~20.2.0Updated only
@schematics/angular~20.2.0Updated only
@angular-devkit/architect~0.2002.0Updated only
@angular-devkit/build-webpack~0.2002.0Updated only
@angular/core~20.2.0Added if not installed
@angular/material~20.2.0Updated only
@angular/cdk~20.2.0Updated only
@angular/google-maps~20.2.0Updated only
ng-packagr~20.2.0Updated only

Version: 21.5.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^20.2.0Updated only
@angular-eslint/eslint-plugin^20.2.0Updated only
@angular-eslint/eslint-plugin-template^20.2.0Updated only
@angular-eslint/template-parser^20.2.0Updated only
@angular-eslint/utils^20.2.0Updated only
@angular-eslint/schematics^20.2.0Updated only
@angular-eslint/test-utils^20.2.0Updated only
@angular-eslint/builder^20.2.0Updated only
@angular-eslint/bundled-angular-compiler^20.2.0Updated only

Version: 21.5.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin^20.2.0Updated only
@angular-eslint/eslint-plugin-template^20.2.0Updated only
@angular-eslint/template-parser^20.2.0Updated only
@angular-eslint/utils^20.2.0Updated only
@angular-eslint/schematics^20.2.0Updated only
@angular-eslint/test-utils^20.2.0Updated only
@angular-eslint/builder^20.2.0Updated only
@angular-eslint/bundled-angular-compiler^20.2.0Updated only

Version: 21.4.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^20.0.0Updated only

Version: 21.3.0-beta.4

Update the @angular/cli package version to ~20.1.0.

NameVersion
@angular/core>=20.1.0

Update the @angular/cli package version in the package.json file at the workspace root to ~20.1.0.

package.json
{
"devDependencies": {
"@angular/cli": "~20.0.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~20.1.0"
}
}

Version: 21.3.0-beta.4

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~20.1.0Updated only
@angular-devkit/core~20.1.0Updated only
@angular-devkit/schematics~20.1.0Updated only
@angular/build~20.1.0Updated only
@angular/pwa~20.1.0Updated only
@angular/ssr~20.1.0Updated only
@schematics/angular~20.1.0Updated only
@angular-devkit/architect~0.2001.0Updated only
@angular-devkit/build-webpack~0.2001.0Updated only
@angular/core~20.1.0Added if not installed
@angular/material~20.1.0Updated only
@angular/cdk~20.1.0Updated only
@angular/google-maps~20.1.0Updated only
ng-packagr~20.1.0Updated only

Version: 21.2.0-beta.3

Update the @angular/cli package version to ~20.0.0.

NameVersion
@angular/core>=20.0.0

Update the @angular/cli package version in the package.json file at the workspace root to ~20.0.0.

package.json
{
"devDependencies": {
"@angular/cli": "~19.2.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~20.0.0"
}
}

Version: 21.2.0-beta.3

Migrate imports of provideServerRendering from @angular/platform-server to @angular/ssr.

NameVersion
@angular/core>=20.0.0

Migrate Imports of provideServerRendering from @angular/platform-server to @angular/ssr

Section titled “Migrate Imports of provideServerRendering from @angular/platform-server to @angular/ssr”

Migrate the imports of provideServerRendering from @angular/platform-server to @angular/ssr. This migration will also add the @angular/ssr package to your dependencies if needed.

Change the import of provideServerRendering from @angular/platform-server to @angular/ssr:

app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering()],
};
app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/ssr';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering()],
};

If you already have imports from @angular/ssr, the migration will add provideServerRendering to the existing import:

app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
import { provideServerRouting } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering(), provideServerRouting(serverRoutes)],
};
app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRouting, provideServerRendering } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering(), provideServerRouting(serverRoutes)],
};

Version: 21.2.0-beta.3

Replace provideServerRouting and provideServerRoutesConfig with provideServerRendering using withRoutes.

NameVersion
@angular/core>=20.0.0

Replace provideServerRouting and provideServerRoutesConfig with provideServerRendering

Section titled “Replace provideServerRouting and provideServerRoutesConfig with provideServerRendering”

Replace provideServerRouting and provideServerRoutesConfig calls with provideServerRendering using withRoutes.

Remove provideServerRouting from your providers array and update the provideServerRendering call to use withRoutes:

app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering, provideServerRouting } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering(), provideServerRouting(serverRoutes)],
};
app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering, withRoutes } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering(withRoutes(serverRoutes))],
};

If you have provideServerRouting with additional arguments, the migration will preserve them:

app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import {
provideServerRendering,
provideServerRouting,
withAppShell,
} from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(),
provideServerRouting(serverRoutes, withAppShell(AppShellComponent)),
],
};
app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering, withAppShell, withRoutes } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(
withRoutes(serverRoutes),
withAppShell(AppShellComponent)
),
],
};

Remove provideServerRoutesConfig from your providers array and update the provideServerRendering call to use withRoutes:

app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import {
provideServerRendering,
provideServerRoutesConfig,
withAppShell,
} from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(),
provideServerRoutesConfig(serverRoutes, withAppShell(AppShellComponent)),
],
};
app/app.config.server.ts
import { ApplicationConfig } from '@angular/core';
import { provideServerRendering, withAppShell, withRoutes } from '@angular/ssr';
import { serverRoutes } from './app.routes.server';
const serverConfig: ApplicationConfig = {
providers: [
provideServerRendering(
withRoutes(serverRoutes),
withAppShell(AppShellComponent)
),
],
};

set-generator-defaults-for-previous-style-guide

Section titled “set-generator-defaults-for-previous-style-guide”

Version: 21.2.0-beta.3

Update the generator defaults to maintain the previous style guide behavior.

NameVersion
@angular/core>=20.0.0

Set Generator Defaults for Previous Style Guide

Section titled “Set Generator Defaults for Previous Style Guide”

Updates the generator defaults in the nx.json file to maintain the previous Angular Style Guide behavior. This ensures that newly generated code in existing workspaces follows the same conventions as the existing codebase.

The migration will add default configurations for the relevant Angular generators in the workspace’s nx.json file:

nx.json
{
"generators": {}
}
nx.json
{
"generators": {
"@nx/angular:component": {
"type": "component"
},
"@nx/angular:directive": {
"type": "directive"
},
"@nx/angular:service": {
"type": "service"
},
"@nx/angular:scam": {
"type": "component"
},
"@nx/angular:scam-directive": {
"type": "directive"
},
"@nx/angular:guard": {
"typeSeparator": "."
},
"@nx/angular:interceptor": {
"typeSeparator": "."
},
"@nx/angular:module": {
"typeSeparator": "."
},
"@nx/angular:pipe": {
"typeSeparator": "."
},
"@nx/angular:resolver": {
"typeSeparator": "."
},
"@schematics/angular:component": {
"type": "component"
},
"@schematics/angular:directive": {
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
}
}

If some of the generator defaults are already set, the migration will not override them:

nx.json
{
"generators": {
"@nx/angular:component": {
"type": "cmp"
},
"@schematics/angular:component": {
"type": "cmp"
},
"@nx/angular:interceptor": {
"typeSeparator": "-"
},
"@schematics/angular:interceptor": {
"typeSeparator": "-"
}
}
}
nx.json
{
"generators": {
"@nx/angular:component": {
"type": "cmp"
},
"@schematics/angular:component": {
"type": "cmp"
},
"@nx/angular:interceptor": {
"typeSeparator": "-"
},
"@schematics/angular:interceptor": {
"typeSeparator": "-"
},
"@nx/angular:directive": {
"type": "directive"
},
"@nx/angular:service": {
"type": "service"
},
"@nx/angular:scam": {
"type": "component"
},
"@nx/angular:scam-directive": {
"type": "directive"
},
"@nx/angular:guard": {
"typeSeparator": "."
},
"@nx/angular:module": {
"typeSeparator": "."
},
"@nx/angular:pipe": {
"typeSeparator": "."
},
"@nx/angular:resolver": {
"typeSeparator": "."
},
"@schematics/angular:directive": {
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
}
}

Version: 21.2.0-beta.3

Update ‘moduleResolution’ to ‘bundler’ in TypeScript configurations. You can read more about this here: https://www.typescriptlang.org/tsconfig/#moduleResolution.

NameVersion
@angular/core>=20.0.0

Update moduleResolution to bundler in TypeScript configurations

Section titled “Update moduleResolution to bundler in TypeScript configurations”

Updates the TypeScript moduleResolution option to 'bundler' for improved compatibility with modern package resolution algorithms used by bundlers like Webpack, Vite, and esbuild.

The migration will update TypeScript configuration files in your workspace to use the 'bundler' module resolution strategy:

apps/app1/tsconfig.app.json
{
"compilerOptions": {
"module": "es2020",
"moduleResolution": "node"
}
}
apps/app1/tsconfig.app.json
{
"compilerOptions": {
"module": "es2020",
"moduleResolution": "bundler"
}
}

If the moduleResolution is already set to 'bundler' or the module is set to 'preserve', the migration will not modify the configuration:

apps/app1/tsconfig.app.json
{
"compilerOptions": {
"module": "preserve",
"moduleResolution": "node"
}
}
apps/app1/tsconfig.app.json
{
"compilerOptions": {
"module": "preserve",
"moduleResolution": "node"
}
}

Version: 21.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~20.0.0Updated only
@angular-devkit/core~20.0.0Updated only
@angular-devkit/schematics~20.0.0Updated only
@angular/build~20.0.0Updated only
@angular/pwa~20.0.0Updated only
@angular/ssr~20.0.0Updated only
@schematics/angular~20.0.0Updated only
@angular-devkit/architect~0.2000.0Updated only
@angular-devkit/build-webpack~0.2000.0Updated only
@angular/core~20.0.0Added if not installed
@angular/material~20.0.0Updated only
@angular/cdk~20.0.0Updated only
@angular/google-maps~20.0.0Updated only
ng-packagr~20.0.0Updated only

Version: 21.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^20.0.0Updated only

Version: 21.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin^20.0.0Updated only
@angular-eslint/eslint-plugin-template^20.0.0Updated only
@angular-eslint/template-parser^20.0.0Updated only
@angular-eslint/utils^20.0.0Updated only
@angular-eslint/schematics^20.0.0Updated only
@angular-eslint/test-utils^20.0.0Updated only
@angular-eslint/builder^20.0.0Updated only
@angular-eslint/bundled-angular-compiler^20.0.0Updated only

Version: 21.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@nx/angular-rspack^21.1.0Updated only

Version: 21.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~14.6.0Updated only

Version: 21.1.0-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@nx/angular-rspack^21.0.1Updated only

Version: 21.0.0-beta.3

Set the continuous option to true for continuous tasks.

Set continuous Option for Continuous Tasks

Section titled “Set continuous Option for Continuous Tasks”

This migration sets the continuous option to true for tasks that are known to run continuously, and only if the option is not already explicitly set.

Specifically, it updates Angular targets using the following executors:

  • @angular-devkit/build-angular:dev-server
  • @angular-devkit/build-angular:ssr-dev-server
  • @nx/angular:dev-server
  • @nx/angular:module-federation-dev-server
  • @nx/angular:module-federation-dev-ssr
apps/app1/project.json
{
// ...
"targets": {
// ...
"serve": {
"executor": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "my-app:build",
"port": 4200
}
}
}
}
apps/app1/project.json
{
// ...
"targets": {
// ...
"serve": {
"continuous": true,
"executor": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "my-app:build",
"port": 4200
}
}
}
}

When a target is already explicitly configured with a continuous option, the migration will not modify it:

apps/app1/project.json
{
// ...
"targets": {
// ...
"serve": {
"continuous": false,
"executor": "@nx/angular:dev-server",
"options": {
"buildTarget": "my-app:build",
"port": 4200
}
}
}
}
apps/app1/project.json
{
// ...
"targets": {
// ...
"serve": {
"continuous": false,
"executor": "@nx/angular:dev-server",
"options": {
"buildTarget": "my-app:build",
"port": 4200
}
}
}
}

change-data-persistence-operators-imports-to-ngrx-router-store-data-persistence

Section titled “change-data-persistence-operators-imports-to-ngrx-router-store-data-persistence”

Version: 21.0.0-beta.5

Change the data persistence operator imports to ‘@ngrx/router-store/data-persistence’.

NameVersion
@ngrx/store>=16.0.0

Change the Data Persistence Operator Imports from @nx/angular to @ngrx/router-store/data-persistence

Section titled “Change the Data Persistence Operator Imports from @nx/angular to @ngrx/router-store/data-persistence”

The data persistence operators (fetch, navigation, optimisticUpdate, and pessimisticUpdate) have been deprecated for a while and are now removed from the @nx/angular package. This migration automatically updates your import statements to use the @ngrx/router-store/data-persistence module and adds @ngrx/router-store to your dependencies if needed.

If you import only data persistence operators from @nx/angular, the migration will update the import path to @ngrx/router-store/data-persistence.

apps/app1/src/app/users/users.effects.ts
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { fetch } from '@nx/angular';
@Injectable()
export class UsersEffects {
// ...
}
apps/app1/src/app/users/users.effects.ts
import { Injectable } from '@angular/core';
import { fetch } from '@ngrx/router-store/data-persistence';
@Injectable()
export class UsersEffects {
// ...
}

If you import multiple data persistence operators from @nx/angular, the migration will update the import path for all of them.

apps/app1/src/app/users/users.effects.ts
import { Injectable } from '@angular/core';
import { fetch, navigation } from '@nx/angular';
@Injectable()
export class UsersEffects {
// ...
}
apps/app1/src/app/users/users.effects.ts
import { Injectable } from '@angular/core';
import { fetch, navigation } from '@ngrx/router-store/data-persistence';
@Injectable()
export class UsersEffects {
// ...
}

If your imports mix data persistence operators with other utilities from @nx/angular, the migration will split them into separate import statements.

apps/app1/src/app/users/users.effects.ts
import { Injectable } from '@angular/core';
import { fetch, someExtraUtility, navigation } from '@nx/angular';
@Injectable()
export class UsersEffects {
// ...
}
apps/app1/src/app/users/users.effects.ts
import { Injectable } from '@angular/core';
import { fetch, navigation } from '@ngrx/router-store/data-persistence';
import { someExtraUtility } from '@nx/angular';
@Injectable()
export class UsersEffects {
// ...
}

If you don’t already have @ngrx/router-store in your dependencies, the migration will add it to your package.json.

package.json
{
"dependencies": {
"@nx/angular": "^21.0.0",
"@ngrx/store": "^19.1.0",
"@ngrx/effects": "^19.1.0",
// ...
},
}
package.json
{
"dependencies": {
"@nx/angular": "^21.0.0",
"@ngrx/store": "^19.1.0",
"@ngrx/effects": "^19.1.0",
"@ngrx/router-store": "^19.1.0",
// ...
},
}

Version: 20.8.1-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@nx/angular-rspack^20.7.0Updated only

Version: 20.5.0-beta.5

Update the @angular/cli package version to ~19.2.0.

NameVersion
@angular/core>=19.2.0

Update the @angular/cli package version in the package.json file at the workspace root to ~19.2.0.

package.json
{
"devDependencies": {
"@angular/cli": "~19.1.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~19.2.0"
}
}

Version: 20.5.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~19.2.0Updated only
@angular-devkit/core~19.2.0Updated only
@angular-devkit/schematics~19.2.0Updated only
@angular/build~19.2.0Updated only
@angular/pwa~19.2.0Updated only
@angular/ssr~19.2.0Updated only
@schematics/angular~19.2.0Updated only
@angular-devkit/architect~0.1902.0Updated only
@angular-devkit/build-webpack~0.1902.0Updated only
@angular/core~19.2.0Added if not installed
@angular/material~19.2.1Updated only
@angular/cdk~19.2.1Updated only
@angular/google-maps~19.2.1Updated only
ng-packagr~19.2.0Updated only

Version: 20.5.0-rc.1

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^19.2.0Updated only
@angular-eslint/eslint-plugin^19.2.0Updated only
@angular-eslint/eslint-plugin-template^19.2.0Updated only
@angular-eslint/template-parser^19.2.0Updated only
@angular-eslint/utils^19.2.0Updated only
@angular-eslint/schematics^19.2.0Updated only
@angular-eslint/test-utils^19.2.0Updated only
@angular-eslint/builder^19.2.0Updated only
@angular-eslint/bundled-angular-compiler^19.2.0Updated only

Version: 20.4.0-beta.1

Update the @angular/cli package version to ~19.1.0.

NameVersion
@angular/core>=19.1.0

Update the version of the Angular CLI if it is specified in package.json

Update in devDependencies:

package.json
{
"devDependencies": {
"@angular/cli": "~13.3.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~19.1.0"
}
}

Update in dependencies:

package.json
{
"dependencies": {
"@angular/cli": "~13.3.0"
}
}
package.json
{
"dependencies": {
"@angular/cli": "~19.1.0"
}
}

Version: 20.4.0-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~19.1.0Updated only
@angular-devkit/core~19.1.0Updated only
@angular-devkit/schematics~19.1.0Updated only
@angular/build~19.1.0Updated only
@angular/pwa~19.1.0Updated only
@angular/ssr~19.1.0Updated only
@schematics/angular~19.1.0Updated only
@angular-devkit/architect~0.1901.0Updated only
@angular-devkit/build-webpack~0.1901.0Updated only
@angular/core~19.1.0Added if not installed
@angular/material~19.1.0Updated only
@angular/cdk~19.1.0Updated only
@angular/google-maps~19.1.0Updated only
ng-packagr~19.1.0Updated only

Version: 20.3.0-beta.2

If workspace includes Module Federation projects, ensure the new @nx/module-federation package is installed.

Ensure the @nx/module-federation Package is Installed

Section titled “Ensure the @nx/module-federation Package is Installed”

If workspace includes Module Federation projects, ensure the new @nx/module-federation package is installed.

package.json
{
"dependencies": {}
}
package.json
{
"dependencies": {
"@nx/module-federation": "20.3.0"
}
}

Version: 20.3.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^19.0.0Updated only

update-20-2-0-update-module-federation-config-import

Section titled “update-20-2-0-update-module-federation-config-import”

Version: 20.2.0-beta.2

Update the ModuleFederationConfig import use @nx/module-federation.

Migrate Module Federation Imports to New Package

Section titled “Migrate Module Federation Imports to New Package”

Update the ModuleFederationConfig imports to use @nx/module-federation.

Update import paths for ModuleFederationConfig.

apps/shell/webpack.config.js
import { ModuleFederationConfig } from '@nx/webpack';
apps/shell/webpack.config.js
import { ModuleFederationConfig } from '@nx/module-federation';

update-20-2-0-update-with-module-federation-import

Section titled “update-20-2-0-update-with-module-federation-import”

Version: 20.2.0-beta.2

Update the withModuleFederation import use @nx/module-federation/angular.

Migrate withModuleFederation Import to New Package

Section titled “Migrate withModuleFederation Import to New Package”

Update the withModuleFederation import to use @nx/module-federation/webpack.

Update import paths for withModuleFederation and withModuleFederationForSSR.

apps/shell/webpack.config.ts
import {
withModuleFederation,
withModuleFederationForSSR,
} from '@nx/angular/module-federation';
apps/shell/webpack.config.ts
import {
withModuleFederation,
withModuleFederationForSSR,
} from '@nx/module-federation/angular';

Version: 20.2.0-beta.5

Update the @angular/cli package version to ~19.0.0.

NameVersion
@angular/core>=19.0.0

Update the version of the Angular CLI if it is specified in package.json

Update in devDependencies:

package.json
{
"devDependencies": {
"@angular/cli": "~13.3.0"
}
}
package.json
{
"devDependencies": {
"@angular/cli": "~19.0.0"
}
}

Update in dependencies:

package.json
{
"dependencies": {
"@angular/cli": "~13.3.0"
}
}
package.json
{
"dependencies": {
"@angular/cli": "~19.0.0"
}
}

Version: 20.2.0-beta.5

Add the ‘@angular/localize/init’ polyfill to the ‘polyfills’ option of targets using esbuild-based executors.

NameVersion
@angular/core>=19.0.0

Add the ‘@angular/localize/init’ polyfill to the ‘polyfills’ option of targets using esbuild-based executors.

Add the @angular/localize/init polyfill to any of these executors:

  • @angular/build:application
  • @angular-devkit/build-angular:application
  • @nx/angular:application
  • @angular-devkit/build-angular:browser-esbuild
  • @nx/angular:browser-esbuild
apps/app1/project.json
{
"targets": {
"build": {
"executor": "@angular/build:application",
"options": {
"localize": true
}
}
}
}
apps/app1/project.json
{
"targets": {
"build": {
"executor": "@angular/build:application",
"options": {
"localize": true,
"polyfills": ["@angular/localize/init"]
}
}
}
}

update-angular-ssr-imports-to-use-node-entry-point

Section titled “update-angular-ssr-imports-to-use-node-entry-point”

Version: 20.2.0-beta.5

Update ‘@angular/ssr’ import paths to use the new ‘/node’ entry point when ‘CommonEngine’ is detected.

NameVersion
@angular/core>=19.0.0

Update Angular SSR Imports to Use Node Entry Point

Section titled “Update Angular SSR Imports to Use Node Entry Point”

Update ‘@angular/ssr’ import paths to use the new ‘/node’ entry point when ‘CommonEngine’ is detected.

Update import paths for SSR CommonEngine properties to use @angular/ssr/node.

apps/app1/server.ts
import { CommonEngine } from '@angular/ssr';
import type {
CommonEngineOptions,
CommonEngineRenderOptions,
} from '@angular/ssr';
apps/app1/server.ts
import { CommonEngine } from '@angular/ssr/node';
import type {
CommonEngineOptions,
CommonEngineRenderOptions,
} from '@angular/ssr/node';

Version: 20.2.0-beta.6

Disable the Angular ESLint prefer-standalone rule if not set.

NameVersion
@angular/core>=19.0.0

Disable the Angular ESLint prefer-standalone rule if not set.

Update import paths for withModuleFederation and withModuleFederationForSSR.

apps/app1/.eslintrc.json
{
"overrides": [
{
"files": ["*.html"],
"rules": {
"some-rule-for-html": "error"
}
}
]
}
apps/app1/.eslintrc.json
{
"overrides": [
{
"files": ["*.html"],
"rules": {
"some-rule-for-html": "error"
}
},
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/prefer-standalone": "off"
}
}
]
}

import { addProjectConfiguration, writeJson, type ProjectConfiguration, type ProjectGraph, type Tree, } from ‘@nx/devkit’; import { createTreeWithEmptyWorkspace } from ‘@nx/devkit/testing’; import migration from ’./disable-angular-eslint-prefer-standalone’;

let projectGraph: ProjectGraph; jest.mock(‘@nx/devkit’, () => ({ …jest.requireActual(‘@nx/devkit’), createProjectGraphAsync: () => Promise.resolve(projectGraph), }));

describe(‘disable-angular-eslint-prefer-standalone’, () => { let tree: Tree;

beforeEach(() => { tree = createTreeWithEmptyWorkspace();

const projectConfig: ProjectConfiguration = {
name: 'app1',
root: 'apps/app1',
};
projectGraph = {
dependencies: {
app1: [
{
source: 'app1',
target: 'npm:@angular/core',
type: 'static',
},
],
},
nodes: {
app1: {
data: projectConfig,
name: 'app1',
type: 'app',
},
},
};
addProjectConfiguration(tree, projectConfig.name, projectConfig);

});

describe(‘.eslintrc.json’, () => { it(‘should not disable @angular-eslint/prefer-standalone when it is set’, async () => { writeJson(tree, ‘apps/app1/.eslintrc.json’, { overrides: [ { files: [‘*.ts’], rules: { ‘@angular-eslint/prefer-standalone’: [‘error’] }, }, ], });

await migration(tree);
expect(tree.read('apps/app1/.eslintrc.json', 'utf8'))
.toMatchInlineSnapshot(`
"{
"overrides": [
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/prefer-standalone": ["error"]
}
}
]
}
"
`);
});
it('should not disable @angular-eslint/prefer-standalone when there are multiple overrides for angular eslint and the rule is set in one of them', async () => {
writeJson(tree, 'apps/app1/.eslintrc.json', {
overrides: [
{
files: ['*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{ type: 'attribute', prefix: 'app', style: 'camelCase' },
],
},
},
{
files: ['*.ts'],
rules: { '@angular-eslint/prefer-standalone': ['error'] },
},
],
});
await migration(tree);
expect(tree.read('apps/app1/.eslintrc.json', 'utf8'))
.toMatchInlineSnapshot(`
"{
"overrides": [
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
]
}
},
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/prefer-standalone": ["error"]
}
}
]
}
"
`);
});
it('should disable @angular-eslint/prefer-standalone in an existing override for angular eslint', async () => {
writeJson(tree, 'apps/app1/.eslintrc.json', {
overrides: [
{
files: ['*.ts'],
rules: { 'no-unused-vars': 'error' },
},
{
files: ['*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{ type: 'attribute', prefix: 'app', style: 'camelCase' },
],
},
},
],
});
await migration(tree);
expect(tree.read('apps/app1/.eslintrc.json', 'utf8'))
.toMatchInlineSnapshot(`
"{
"overrides": [
{
"files": ["*.ts"],
"rules": {
"no-unused-vars": "error"
}
},
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/prefer-standalone": "off"
}
}
]
}
"
`);
});
it('should disable @angular-eslint/prefer-standalone in an existing override for ts files', async () => {
writeJson(tree, 'apps/app1/.eslintrc.json', {
overrides: [
{
files: ['*.ts'],
rules: { 'no-unused-vars': 'error' },
},
],
});
await migration(tree);
expect(tree.read('apps/app1/.eslintrc.json', 'utf8'))
.toMatchInlineSnapshot(`
"{
"overrides": [
{
"files": ["*.ts"],
"rules": {
"no-unused-vars": "error",
"@angular-eslint/prefer-standalone": "off"
}
}
]
}
"
`);
});
it('should disable @angular-eslint/prefer-standalone in a new override', async () => {
writeJson(tree, 'apps/app1/.eslintrc.json', {
overrides: [
{
files: ['*.html'],
rules: { 'some-rule-for-html': 'error' },
},
],
});
await migration(tree);
expect(tree.read('apps/app1/.eslintrc.json', 'utf8'))
.toMatchInlineSnapshot(`
"{
"overrides": [
{
"files": ["*.html"],
"rules": {
"some-rule-for-html": "error"
}
},
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/prefer-standalone": "off"
}
}
]
}
"
`);
});

});

describe(‘flat config’, () => { it(‘should not disable @angular-eslint/prefer-standalone when it is set’, async () => { tree.write(‘eslint.config.js’, ‘module.exports = [];’); tree.write( ‘apps/app1/eslint.config.js’, module.exports = [ { files: ['*.ts'], rules: { '@angular-eslint/prefer-standalone': ['error'] }, }, ]; );

await migration(tree);
expect(tree.read('apps/app1/eslint.config.js', 'utf8'))
.toMatchInlineSnapshot(`
"module.exports = [
{
files: ['*.ts'],
rules: { '@angular-eslint/prefer-standalone': ['error'] },
},
];
"
`);
});
it('should not disable @angular-eslint/prefer-standalone when there are multiple overrides for angular eslint and the rule is set in one of them', async () => {
tree.write('eslint.config.js', 'module.exports = [];');
tree.write(
'apps/app1/eslint.config.js',
`module.exports = [
{
files: ['*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{ type: 'attribute', prefix: 'app', style: 'camelCase' },
],
},
},
{
files: ['*.ts'],
rules: { '@angular-eslint/prefer-standalone': ['error'] },
},
];
`
);
await migration(tree);
expect(tree.read('apps/app1/eslint.config.js', 'utf8'))
.toMatchInlineSnapshot(`
"module.exports = [
{
files: ['*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{ type: 'attribute', prefix: 'app', style: 'camelCase' },
],
},
},
{
files: ['*.ts'],
rules: { '@angular-eslint/prefer-standalone': ['error'] },
},
];
"
`);
});
it('should disable @angular-eslint/prefer-standalone in an existing override for angular eslint', async () => {
tree.write('eslint.config.js', 'module.exports = [];');
tree.write(
'apps/app1/eslint.config.js',
`module.exports = [
{
files: ['*.ts'],
rules: { 'no-unused-vars': 'error' },
},
{
files: ['*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{ type: 'attribute', prefix: 'app', style: 'camelCase' },
],
},
},
];
`
);
await migration(tree);
expect(tree.read('apps/app1/eslint.config.js', 'utf8'))
.toMatchInlineSnapshot(`
"module.exports = [
{
files: ['*.ts'],
rules: { 'no-unused-vars': 'error' },
},
{
files: ['**/*.ts'],
rules: {
'@angular-eslint/directive-selector': [
'error',
{
type: 'attribute',
prefix: 'app',
style: 'camelCase',
},
],
'@angular-eslint/prefer-standalone': 'off',
},
},
];
"
`);
});
it('should disable @angular-eslint/prefer-standalone in an existing override for ts files', async () => {
tree.write('eslint.config.js', 'module.exports = [];');
tree.write(
'apps/app1/eslint.config.js',
`module.exports = [
{
files: ['*.ts'],
rules: { 'no-unused-vars': 'error' },
},
];
`
);
await migration(tree);
expect(tree.read('apps/app1/eslint.config.js', 'utf8'))
.toMatchInlineSnapshot(`
"module.exports = [
{
files: ['**/*.ts'],
rules: {
'no-unused-vars': 'error',
'@angular-eslint/prefer-standalone': 'off',
},
},
];
"
`);
});
it('should disable @angular-eslint/prefer-standalone in a new override', async () => {
tree.write('eslint.config.js', 'module.exports = [];');
tree.write(
'apps/app1/eslint.config.js',
`module.exports = [
{
files: ['*.html'],
rules: { 'some-rule-for-html': 'error' },
},
];
`
);
await migration(tree);
expect(tree.read('apps/app1/eslint.config.js', 'utf8'))
.toMatchInlineSnapshot(`
"module.exports = [
{
files: ['*.html'],
rules: { 'some-rule-for-html': 'error' },
},
{
files: ['**/*.ts'],
rules: {
'@angular-eslint/prefer-standalone': 'off',
},
},
];
"
`);
});

}); });

Version: 20.2.0-beta.8

Remove Angular ESLint rules that were removed in v19.0.0.

NameVersion
@angular/core>=19.0.0

Remove Angular ESLint rules that were removed in v19.0.0.

Removes @angular-eslint/no-host-metadata-property, @angular-eslint/sort-ngmodule-metadata-arrays and @angular-eslint/prefer-standalone-component from any ESLint config file. Files to be searched include .eslintrc.json, .eslintrc.base.json, .eslint.config.js and .eslint.config.base.js.

apps/app1/.eslintrc.json
{
"overrides": [
{
"files": ["*.ts"],
"rules": {
"@angular-eslint/no-host-metadata-property": ["error"],
"@angular-eslint/sort-ngmodule-metadata-arrays": ["error"],
"@angular-eslint/prefer-standalone-component": ["error"]
}
}
]
}
apps/app1/.eslintrc.json
{
"overrides": [
{
"files": ["*.ts"],
"rules": {}
}
]
}

remove-tailwind-config-from-ng-packagr-executors

Section titled “remove-tailwind-config-from-ng-packagr-executors”

Version: 20.2.0-beta.8

Remove the deprecated ‘tailwindConfig’ option from ng-packagr executors. Tailwind CSS configurations located at the project or workspace root will be picked up automatically.

NameVersion
@angular/core>=19.0.0

Remove tailwindConfig from ng-packagr Executors

Section titled “Remove tailwindConfig from ng-packagr Executors”

Remove the deprecated ‘tailwindConfig’ option from ng-packagr executors. Tailwind CSS configurations located at the project or workspace root will be picked up automatically.

Remove tailwindConfig from the @nx/angular:ng-packagr-lite or @nx/angular:package executor options in project configuration.

libs/my-lib/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"options": {
"project": "libs/lib1/ng-package.json",
"tailwindConfig": "libs/lib1/tailwind.config.js"
}
}
}
}
libs/my-lib/project.json
{
"targets": {
"build": {
"executor": "@nx/angular:ng-packagr-lite",
"options": {
"project": "libs/lib1/ng-package.json"
}
}
}
}

Remove tailwindConfig from the @nx/angular:ng-packagr-lite or @nx/angular:package executor target defaults in nx.json.

nx.json
{
"targetDefaults": {
"@nx/angular:ng-packagr-lite": {
"options": {
"project": "{projectRoot}/ng-package.json",
"tailwindConfig": "{projectRoot}/tailwind.config.js"
}
}
}
}
nx.json
{
"targetDefaults": {
"@nx/angular:ng-packagr-lite": {
"options": {
"project": "{projectRoot}/ng-package.json"
}
}
}
}

Version: 20.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@module-federation/enhanced0.7.6Updated only
@module-federation/runtime0.7.6Updated only
@module-federation/sdk0.7.6Updated only
@module-federation/node2.6.11Updated only

Version: 20.2.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~19.0.0Updated only
@angular-devkit/core~19.0.0Updated only
@angular-devkit/schematics~19.0.0Updated only
@angular/build~19.0.0Updated only
@angular/pwa~19.0.0Updated only
@angular/ssr~19.0.0Updated only
@schematics/angular~19.0.0Updated only
@angular-devkit/architect~0.1900.0Updated only
@angular-devkit/build-webpack~0.1900.0Updated only
@angular/core~19.0.0Added if not installed
@angular/material~19.0.0Updated only
@angular/cdk~19.0.0Updated only
@angular/google-maps~19.0.0Updated only
ng-packagr~19.0.0Updated only
zone.js~0.15.0Updated only

Version: 20.2.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~14.4.0Updated only

Version: 20.2.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^19.0.0Updated only
@angular-eslint/eslint-plugin^19.0.0Updated only
@angular-eslint/eslint-plugin-template^19.0.0Updated only
@angular-eslint/template-parser^19.0.0Updated only
@angular-eslint/utils^19.0.0Updated only
@angular-eslint/schematics^19.0.0Updated only
@angular-eslint/test-utils^19.0.0Updated only
@angular-eslint/builder^19.0.0Updated only
@angular-eslint/bundled-angular-compiler^19.0.0Updated only

Version: 20.2.0-beta.7

The following packages will be updated:

NameVersionAlways add to package.json
@analogjs/vitest-angular~1.10.0Updated only
@analogjs/vite-plugin-angular~1.10.0Updated only

Version: 20.2.2-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
angular-eslint^19.0.2Updated only
@angular-eslint/eslint-plugin^19.0.2Updated only
@angular-eslint/eslint-plugin-template^19.0.2Updated only
@angular-eslint/template-parser^19.0.2Updated only
@angular-eslint/utils^19.0.2Updated only
@angular-eslint/schematics^19.0.2Updated only
@angular-eslint/test-utils^19.0.2Updated only
@angular-eslint/builder^19.0.2Updated only
@angular-eslint/bundled-angular-compiler^19.0.2Updated only

Version: 19.7.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@module-federation/enhanced~0.6.0Updated only
@module-federation/node~2.5.0Updated only

Version: 19.6.0-beta.4

Ensure Module Federation DTS is turned off by default.

Version: 19.6.0-beta.7

Update the @angular/cli package version to ~18.2.0.

NameVersion
@angular/core>=18.2.0

update-19-6-1-ensure-module-federation-target-defaults

Section titled “update-19-6-1-ensure-module-federation-target-defaults”

Version: 19.6.1-beta.0

Ensure Target Defaults are set correctly for Module Federation.

Version: 19.6.0-beta.7

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~18.2.0Updated only
@angular-devkit/core~18.2.0Updated only
@angular-devkit/schematics~18.2.0Updated only
@angular/build~18.2.0Updated only
@angular/pwa~18.2.0Updated only
@angular/ssr~18.2.0Updated only
@schematics/angular~18.2.0Updated only
@angular-devkit/architect~0.1802.0Updated only
@angular-devkit/build-webpack~0.1802.0Updated only
@angular/core~18.2.0Added if not installed
@angular/material~18.2.0Updated only
@angular/cdk~18.2.0Updated only
ng-packagr~18.2.0Updated only
zone.js~0.14.10Updated only

Version: 19.6.1-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^18.0.2Updated only

Version: 19.5.0-beta.1

Update the @angular/cli package version to ~18.1.0.

NameVersion
@angular/core>=18.1.0

Version: 19.5.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@module-federation/node^2.3.0Updated only

Version: 19.5.0-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~18.1.0Updated only
@angular-devkit/core~18.1.0Updated only
@angular-devkit/schematics~18.1.0Updated only
@angular/build~18.1.0Updated only
@angular/pwa~18.1.0Updated only
@angular/ssr~18.1.0Updated only
@schematics/angular~18.1.0Updated only
@angular-devkit/architect~0.1801.0Updated only
@angular-devkit/build-webpack~0.1801.0Updated only
@angular/core~18.1.0Added if not installed
@angular/material~18.1.0Updated only
@angular/cdk~18.1.0Updated only
ng-packagr~18.1.0Updated only

Version: 19.5.4-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^18.0.1Updated only
@ngrx/operators^18.0.1Updated only

Version: 19.4.0-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store^18.0.0Updated only

Version: 19.2.1-beta.0

Installs the ‘@typescript-eslint/utils’ package when having installed ‘@angular-eslint/eslint-plugin’ or ‘@angular-eslint/eslint-plugin-template’ with version >=18.0.0.

NameVersion
@angular-eslint/eslint-plugin>=18.0.0

Version: 19.1.0-beta.2

Update the @angular/cli package version to ~18.0.0.

NameVersion
@angular/core>=18.0.0

Version: 19.1.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~18.0.0Updated only
@angular-devkit/core~18.0.0Updated only
@angular-devkit/schematics~18.0.0Updated only
@angular/pwa~18.0.0Updated only
@angular/ssr~18.0.0Updated only
@schematics/angular~18.0.0Updated only
@angular-devkit/architect~0.1800.0Updated only
@angular-devkit/build-webpack~0.1800.0Updated only
@angular/core~18.0.0Added if not installed
@angular/material~18.0.0Updated only
@angular/cdk~18.0.0Updated only
ng-packagr~18.0.0Updated only

Version: 19.1.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~14.1.0Updated only

Version: 19.1.2-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin^18.0.1Updated only
@angular-eslint/eslint-plugin-template^18.0.1Updated only
@angular-eslint/template-parser^18.0.1Updated only
@angular-eslint/utils^18.0.1Updated only
@angular-eslint/schematics^18.0.1Updated only
@angular-eslint/test-utils^18.0.1Updated only
@angular-eslint/builder^18.0.1Updated only
@angular-eslint/bundled-angular-compiler^18.0.1Updated only

Version: 18.2.0-beta.0

Update the @angular/cli package version to ~17.3.0.

NameVersion
@angular/core>=17.3.0

Version: 18.2.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~17.3.0Updated only
@angular-devkit/core~17.3.0Updated only
@angular-devkit/schematics~17.3.0Updated only
@angular/pwa~17.3.0Updated only
@angular/ssr~17.3.0Updated only
@schematics/angular~17.3.0Updated only
@angular-devkit/architect~0.1703.0Updated only
@angular-devkit/build-webpack~0.1703.0Updated only
@angular/core~17.3.0Added if not installed
@angular/material~17.3.0Updated only
@angular/cdk~17.3.0Updated only
ng-packagr~17.3.0Updated only

Version: 18.2.0-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin~17.3.0Updated only
@angular-eslint/eslint-plugin-template~17.3.0Updated only
@angular-eslint/template-parser~17.3.0Updated only

Version: 18.1.0-beta.1

Update the @angular/cli package version to ~17.2.0.

NameVersion
@angular/core>=17.2.0

Version: 18.1.1-beta.0

Ensure targetDefaults inputs for task hashing when ‘@nx/angular:webpack-browser’ is used are correct for Module Federation.

Version: 18.1.0-beta.2

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~14.0.3Updated only

Version: 18.1.0-beta.1

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~17.2.0Updated only
@angular-devkit/core~17.2.0Updated only
@angular-devkit/schematics~17.2.0Updated only
@angular/pwa~17.2.0Updated only
@angular/ssr~17.2.0Updated only
@schematics/angular~17.2.0Updated only
@angular-devkit/architect~0.1702.0Updated only
@angular-devkit/build-webpack~0.1702.0Updated only
@angular/core~17.2.0Added if not installed
@angular/material~17.2.0Updated only
@angular/cdk~17.2.0Updated only
ng-packagr~17.2.0Updated only

add-module-federation-env-var-to-target-defaults

Section titled “add-module-federation-env-var-to-target-defaults”

Version: 18.0.0-beta.0

Add NX_MF_DEV_SERVER_STATIC_REMOTES to inputs for task hashing when ‘@nx/angular:webpack-browser’ is used for Module Federation.

Version: 17.3.0-beta.10

Update the @angular/cli package version to ~17.1.0.

NameVersion
@angular/core>=17.1.0

Version: 17.3.0-beta.10

Add ‘browser-sync’ as dev dependency when ‘@angular-devkit/build-angular:ssr-dev-server’ or ‘@nx/angular:module-federation-dev-ssr’ is used.

NameVersion
@angular/core>=17.1.0

Version: 17.3.0-beta.10

Add ‘autoprefixer’ as dev dependency when ‘@nx/angular:ng-packagr-lite’ or ‘@nx/angular:package` is used.

NameVersion
@angular/core>=17.1.0

Version: 17.3.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@types/node^18.16.9Updated only

Version: 17.3.0-beta.10

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/build-angular~17.1.0Updated only
@angular-devkit/core~17.1.0Updated only
@angular-devkit/schematics~17.1.0Updated only
@angular/pwa~17.1.0Updated only
@angular/ssr~17.1.0Updated only
@schematics/angular~17.1.0Updated only
@angular-devkit/architect~0.1701.0Updated only
@angular-devkit/build-webpack~0.1701.0Updated only
@angular/core~17.1.0Added if not installed
@angular/material~17.1.0Updated only
@angular/cdk~17.1.0Updated only
ng-packagr~17.1.0Updated only
zone.js~0.14.3Updated only

Version: 17.2.0-beta.2

Rename ‘@nx/angular:webpack-dev-server’ executor to ‘@nx/angular:dev-server’

Version: 17.2.0-beta.3

The following packages will be updated:

NameVersionAlways add to package.json
@ngrx/store~17.0.0Updated only

Version: 17.1.0-beta.5

Update the @angular/cli package version to ~17.0.0.

NameVersion
@angular/core>=17.0.0

Version: 17.1.0-beta.5

Rename ‘browserTarget’ to ‘buildTarget’.

NameVersion
@angular/core>=17.0.0

Version: 17.1.0-beta.5

Replace usages of ‘@nguniversal/builders’ with ‘@angular-devkit/build-angular’.

NameVersion
@angular/core>=17.0.0

Version: 17.1.0-beta.5

Replace usages of ‘@nguniversal/’ packages with ‘@angular/ssr’.

NameVersion
@angular/core>=17.0.0

Version: 17.1.0-beta.5

Replace the deep imports from ‘zone.js/dist/zone’ and ‘zone.js/dist/zone-testing’ with ‘zone.js’ and ‘zone.js/testing’.

NameVersion
@angular/core>=17.0.0

Version: 17.1.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
@angular-devkit/architect~0.1700.0Updated only
@angular-devkit/build-angular~17.0.0Updated only
@angular-devkit/build-webpack~0.1700.0Updated only
@angular-devkit/core~17.0.0Updated only
@angular-devkit/schematics~17.0.0Updated only
@angular/pwa~17.0.0Updated only
@angular/core~17.0.0Added if not installed
@angular/material~17.0.0Updated only
@angular/cdk~17.0.0Updated only
@schematics/angular~17.0.0Updated only
ng-packagr~17.0.0Updated only
zone.js~0.14.0Updated only

Version: 17.1.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~13.1.3Updated only

Version: 17.1.0-beta.5

The following packages will be updated:

NameVersionAlways add to package.json
@angular-eslint/eslint-plugin~17.0.0Updated only
@angular-eslint/eslint-plugin-template~17.0.0Updated only
@angular-eslint/template-parser~17.0.0Updated only

Version: 17.1.3-beta.0

The following packages will be updated:

NameVersionAlways add to package.json
jest-preset-angular~13.1.4Updated only