npm / @angular/cli
@angular/cli
What changed in @angular/cli 20 to 22, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
31 breaking15 security7 deprecations23 new APIs and options14 performance41 behavior and defaults79 tooling145 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@angular/cli 22172 changes
Breaking changes 18
A prerendering failure now fails the build and excludes the affected routes.
The CLI no longer searches the current directory for bare executable names on Windows.
Updating catalog packages now aborts and guides developers through manual mitigation when needed.
The CLI no longer allows a registry environment variable to override Yarn's registry during updates.
All route parameters are replaced when resolving relative redirects.
Removes the unused outDir setting from the generated app tsconfig.
The default workspace VS Code mcp.json configuration is removed.
Options now take precedence over environment variables.
Application builder output paths are restricted to the output directory.
SSR no longer falls back to CSR for requests that fail host validation; unrecognized Host headers return 400, so valid hosts must be configured.
The package is no longer available; the architect CLI tool has moved to @angular-devkit/architect.
The experimental Jest builder has been removed.
The experimental Web Test Runner builder has been removed.
istanbul-lib-instrument is now an optional peer dependency; Karma projects using code coverage must ensure it is installed.
Node.js v20 is no longer supported; the minimum supported versions are v22.22.0 and v24.13.1.
The application builder option experimentalPlatform is renamed to platform.
The dev server gives PORT highest priority, overriding angular.json port settings and the --port flag, including the default port 4200.
Proxy headers require explicit opt-in; when trustProxyHeaders is true, all X-Forwarded-* headers are supported.
Security 6
Adds the CSP nonce to stylesheet and modulepreload link elements.
Angular SSR: Path Traversal to Sibling Directories in CommonEngine on Windows
The loader preserves integrity and crossorigin attributes.
The best-practices tool enforces MCP roots and throws when a workspace is outside them; it also handles errors from isAllowedWorkspacePath.
The builder prevents OS command injection.
Dynamically loaded modules receive subresource integrity validation.
Deprecations 6
The splitting option is deprecated because disabling code splitting is no longer needed with Vitest 5.
This API is deprecated; use the standard Web API TextDecoder instead.
This API is deprecated; use the standard Web API TextEncoder instead.
CommonEngine APIs are deprecated in favor of AngularNodeAppEngine or AngularAppEngine.
The @ngtools/webpack loader and plugin are deprecated; use @angular/build instead.
Webpack builders in build-angular and build-webpack are deprecated; use @angular/build builders instead.
New APIs and options 8
Array-form proxy configurations support a string context.
The Vitest browser provider ng-add now adds the browsers option to angular.json.
Adds the --root command-line option to mcp.
The unit-test builder gains an option to enable code splitting.
Vitest isolation can now be disabled from the builder.
The headers option can configure Access-Control-Allow-Origin.
The unit-test builder adds an isolate option.
The unit-test builder adds a quiet option to suppress build noise in unit tests.
Performance 12
Resolves asset patterns concurrently with bounded concurrency.
Aggregate worker allocation is bounded across dominant files.
Concurrent worker allocation is bounded for dominant files.
The worker no longer loads compiler-cli and TypeScript.
Chokidar no longer scans unimported node_modules in watch mode.
Reduces watcher debounce latency for faster incremental rebuilds.
Updating the sourcemap ignore list avoids full JSON parsing.
Prerender routes are batched and in-memory server bundles are shared.
Releases build resources earlier when not running in watch mode.
Avoids buffering the request body when sanitizing headers.
Semaphore backpressure throttling is implemented in JavaScriptTransformer.
Registry query counts are optimized by fetching package metadata lazily.
Behavior and default changes 23
Always uses AOT when extracting i18n messages.
Uses the chokidar watcher when followSymlinks is enabled.
Defaults preloadInitial to false when serviceWorker is enabled.
Recursively ignores output and cache paths while watching.
Temporary package installations are isolated from a parent Yarn workspace.
Supports case-insensitive and alternative license file names.
Always installs the package to inspect its manifest on disk for schematics.
Chunk optimization now uses Rolldown by default.
Angular SSR now supports the standard Forwarded header.
The persistent build cache is shared across Git worktrees.
Chunk optimization is now enabled for server builds.
The Istanbul coverage provider is favored when browser testing is enabled.
The semantic affected-file walk is skipped when type checking is disabled.
The Karma runner now falls back to the build target’s preserveSymlinks option.
The unit-test builder now inherits preserveSymlinks from the build target.
Non-SSG page lookups are no longer cached.
Semaphore backpressure throttling is implemented in PackageManager.
JSON imports are excluded from Vite dependency optimization.
Migrations of the same version are no longer sorted alphabetically.
On the first run, schematic detection falls back to the local package.json.
Chunk optimization is enabled by default with heuristics.
Generated components now default to OnPush change detection.
Generated workspaces rely on the strict template default.
Tooling 33
Disables Vitest fsModuleCache in the unit-test builder.
Sorts discovered unit-test files for deterministic builds.
Emitted HTML assets are now served in the dev-server.
The migration tool now skips components that have a change detection strategy.
Supports splitting browser and server stats JSON files for easier consumption.
Pre-compiles critical CSS plans at build time.
Compiles only included test files.
Code splitting is enabled for Vitest browser tests.
The dev-server Vite cache is kept local to each worktree.
Side-effect annotations are ignored in unit test builds.
The refactor-jasmine-vitest schematic transforms fail() calls to expect.fail().
The i18n inliner traverses the AST with an iterative post-order walker.
Code splitting is disabled for unit test builds.
The Angular schematic generates CLAUDE.md for Claude Code instead of AGENTS.md.
A target is set for Rolldown dependency prebundling in the Vite dev server.
Packages with built-in schematics are added to devDependencies only.
The CLI supports npm 12 metadata arrays and error formats, improving compatibility when using npm 12.
The generated AI configuration now includes Angular MCP server configuration.
A built-in SQLite cache store is available as a fallback.
Builds emit debug IDs to support stable subresource integrity hashes.
Declare devserver_start as not read-only, allowing tools to treat it as a state-changing operation.
Declare devserver_stop as not read-only, allowing tools to treat it as a state-changing operation.
Dependency resolution now supports subproject dependencies in pnpm workspaces.
Library unit tests now automatically inject localize/init.
Library unit tests now load zone.js dynamically.
Registry metadata fetching is supported when using the bun package manager.
The migration now uses null objects and callbacks.
The Karma-to-Vitest migration converts fakeAsync fake timers and migrates flush behavior when used in beforeEach.
The Vitest runner supports Istanbul coverage.
An update migration is added to migrate Karma to Vitest.
ng generate uses the service decorator.
Angular CLI adds support for Node.js 26.0.0.
The Vitest unit test runner supports runtime Zone.js detection.
Fixes and other changes 66
Avoids invalidating the diagnostic cache when a stylesheet changes.
Coalesces external watcher directories to avoid the macOS FSEvents limit.
Accepts array indices with multiple digits.
Continues to work when the package manager is not installed.
Resolves package names in npm workspace members.
Preserves preload metadata for nested empty-path routes.
Resolves relative redirects against the parent route.
Preserves query parameters on relative route redirects.
Ensures Sass importers return global Promise instances.
Avoids stack overflow when chaining many rules.
The migration now keeps the workspace build version.
Keeps the Vite server file watcher disabled in Vitest watch mode.
The SSR dev server preserves the Host header when proxying.
Glob entries in proxy configuration retain their order.
The compiler is now loaded for Vitest TestBed initialization.
The loader now encodes script type.
Spurious polling change events are now deduplicated.
Component updates are reset on each dev-server SSR page request.
The cache now preserves nested workspace paths.
Intermediate files are no longer sharded under worker surplus.
Batch locales are processed sequentially in the worker.
CLI options now correctly parse inline boolean values.
Standalone expression statements are no longer incorrectly marked as pure.
Includes inline component stylesheets among referenced watch files.
Runs setup file hooks for each spec file when coverage is enabled.
Auto-CSP supports standard JavaScript MIME types and case insensitivity.
Unknown options are now named in schema validation errors, making configuration problems easier to identify.
strictPort is disabled when port 0 is used in the dev-server.
The pathname is decoded when constructing the server asset path.
Binary values are preserved in the SQLite cache store.
The web request signal is aborted when the corresponding Node.js request is aborted.
The error message for top-level await is corrected to avoid misleading developers.
The build prevents syntax corruption for Crockford-style enum IIFEs.
The build counts statically imported chunks in the initial total.
The build returns direct file contents for non-Angular TypeScript files.
The build prevents syntax corruption in the oxc transform.
The platform is destroyed when the response stream is cancelled.
Paths in setupFiles are normalized to POSIX for the Vitest runner.
The build returns only the lowest version per target engine.
The guard generator imports UrlSegment instead of using subPath.
Prevents the build process from hanging after an unhandled error.
Retains watched files when an error occurs in the load result cache.
Correctly reports available package updates when running ng update without arguments.
Discovers migrations from installed packages when registry metadata omits them.
Settles when the client disconnects.
Prevents IIFE wrappers from interleaving for adjacent classes in minified files.
Paths from sandboxed execroots are rewritten when running under Bazel.
Update resolution now respects client-side release age settings.
Updates now resolve the correct registry name when package dependencies use npm alias syntax.
The CLI now reverts package.json changes if installation tasks fail during an update.
Safeguard the Karma builder stream controller when it is closed.
Import map integrity keys are now validated as URL-like specifiers.
MCP devserver tool names now conform to the spec regex.
Metafile paths are remapped when the workspace root is a symlink or junction.
Custom config options are preserved in runnerConfig for Vitest.
Drive letter casing is canonicalized for the workspace root on Windows.
Temporary installs now copy the packageManager field and Yarn configuration.
Builder-injected i18n locale data is no longer externalized.
All Vite ID prefixes are stripped from minified code when external dependencies are present.
Update bootstrapping now respects the release age policy.
The command handler now handles package manager errors gracefully.
Response headers are preserved during redirects.
The refactor-jasmine-vitest schematic now maps the browserMode option correctly.
The registry option is now validated as a URL.
Temporary package installation is isolated from the parent pnpm workspace.
The schematic now safely comments out multiline statements during refactoring.
@angular/cli 21166 changes
Breaking changes 11
Removes forceAuth and unscoped credential parsing from registry credential handling.
Asset input paths are asserted to be within the workspace root.
The webpack dev-server no longer applies an unconditional CORS wildcard.
Values of x-forwarded-prefix that start with a backslash are disallowed.
Invalid package manager versions are now rejected with an error.
Using Vitest runtime mocking now fails explicitly.
The library tsconfig template no longer includes inlineSources.
ng commands no longer automatically detect and use cnpm; use .npmrc to configure npm to use the cnpm registry.
The Less javascriptEnabled option is no longer supported; stylesheets using inline JavaScript must be refactored.
TypeScript versions older than 5.9 are no longer supported.
Vitest test isolation is disabled by default, and explicit test isolation configuration is removed.
Security 7
MCP workspace access is restricted to allowed client roots during resolution.
Angular SSR has Open Redirect and Request Steering via Encoded X-Forwarded-Prefix
Adds an option to safely validate and sanitize proxy headers.
Protocol-Relative URL Injection via Single Backslash Bypass in Angular SSR
Angular SSR has an Open Redirect via X-Forwarded-Prefix
Angular SSR is vulnerable to SSRF and Header Injection via request handling pipeline
Validates host headers to prevent header-based SSRF.
Deprecations 1
The matcher now warns about loose matching.
New APIs and options 15
Adds support for configuring trusted proxy headers via an environment variable.
The MCP devserver start tool supports a custom port.
Introduces a DI token to signal the route discovery process.
The unit-test builder now supports a headless option.
The jasmine-vitest schematic adds a browserMode option.
The SSR SSL plugin supports the NODE_EXTRA_CA_CERTS environment variable.
The Vitest coverage reportsDirectory option can now be overridden.
The library schematic now supports the testRunner option.
Adds the addTypeToClassName option to relevant schematics.
Adds a define option to the dev-server.
ng new supports different file name style guides.
Adds an include option to the jasmine-to-vitest schematic.
Adds JSON output to ng version, which also reports more details.
Unit tests can use a custom runner configuration file, including an absolute path.
Adds a Tailwind CSS option to the application schematic and ng new.
Performance 2
Avoids redundant package version resolution.
Package manager discovery now uses stat-based probing.
Behavior and default changes 17
External packages are used for polyfills only when no local files are present.
Custom headers are now supported in redirect responses.
Process environment variables are passed to prerender workers.
Extensionless assets are now served without transformation.
Argument parsing now infers boolean types for the string values 'true' and 'false'.
Argument parsing now infers boolean types for the string values 'true' and 'false'.
Vitest dependency checks are loosened when runnerConfig is used.
Allows application assets to be located in the workspace root.
Uses a project-local temporary directory.
SSR processing is skipped for well-known non-Angular URLs such as favicon.ico.
Management of the Vitest UI option is now conditional.
The migration now silently skips build targets that already use one of the new builders.
The MCP documentation search tool now accounts for the Angular version.
Promotes the MCP find_examples tool to stable and adds version-aware search with structured output.
The MCP tool now accounts for the Angular version.
New applications are zoneless by default.
Promotes the zoneless migration MCP tool to stable.
Tooling 44
The update schematic expands package groups for newly added peer dependencies.
Initial package manager workspace awareness is introduced.
The MCP test tool uses the headless option.
MCP tools dynamically resolve the project’s Angular CLI executable.
Vitest validates V8 coverage support for browsers.
Compatibility checks are simplified, with special handling for local builds of new major versions.
MCP tools now use standardized workspace and project options.
Prettier's formatting list now includes Markdown files.
Generated workspaces now include a .prettierrc file and Prettier as a dev dependency.
Files modified by schematics are now formatted automatically.
File formatting is now integrated into update migrations.
The Angular schematic now supports adding Vitest browser providers.
The schematic now provides actionable feedback.
Vitest browser runs with Playwright using the operating system theme.
Warns when the production configuration is missing for a service worker.
Coverage thresholds can now be merged with Vitest runnerConfig.
Improves file system traversal and symlink handling in the MCP tool.
New workspaces include an MCP configuration file.
Adds MCP tools for testing, end-to-end testing, building, and running dev servers, and adds an experimental all tool group.
The unit-test builder directly supports ng-packagr.
Simplifies SSL handling when serving with SSR.
The migration generates a detailed report of its changes.
Adds signal forms lessons.
TestBed teardown is disabled during debugging in Vitest.
Injects source-map-support for browser tests.
Module-based application schematics now use provideZoneChangeDetection in the root module.
Custom middleware presents an Angular-tailored message.
Testing polyfills are injected in the Karma unit-test executor.
The built-in test main file conditionally provides Zone.js change detection.
Filename truncation was added to test discovery.
The Jasmine-to-Vitest migration now includes mock names in its createSpyObj transformation.
The ai-config schematic supports AGENTS.md.
Adds an ai-tutor MCP tool.
Introduces a schematic to refactor unit tests from Jasmine to Vitest, including transformations for spy APIs, matchers, and other constructs.
Adds builder information, style-language and unit-test-framework detection, and improved workspace discovery in monorepos.
Adds advanced filtering, snippet support, and multi-database search to the MCP example search tool.
Adds a migration to update moduleResolution to bundler.
Adds fallback support for packages without direct ng add functionality and provides detailed peer dependency conflict errors.
Dry runs show planned actions; dependency lookups are cached and peer dependency checks are parallelized.
Overhauls command output with more details, including Vitest.
New projects set packageManager in package.json.
New projects are configured for Vitest and can choose a test runner.
The unit-test builder supports .test.ts files by default and adds options for listing and filtering tests, coverage, reporters, and browser viewport.
zone.js is optional in server and app-shell builders.
Fixes and other changes 69
Prevents the esbuild service from leaking child processes.
Virtual esbuild paths with (disabled) are ignored.
npm manifests represented as arrays are now parsed robustly.
The refactor adds missing imports for the focus and skip APIs.
Route segments are decoded when building and matching the route tree.
The router normalizes URLs for comparison.
The app-shell route format is fixed.
HMR component update path resolution uses rootDir.
MCP project scans ignore EBADF file system errors.
The prerender builder ensures routes have a leading slash.
Handles a missing package manager during analytics initialization.
Scopes the Chrome executable path to individual Playwright instances.
Preserves error stack traces during prerendering.
Ensures errors from transitive SCSS partials are tracked in watch mode.
Fixes sourceRoot resolution for the MCP projects tool.
Ensures Vitest mock patching runs only once.
Console methods are restored after the logger completes.
Migrate-only updates use the parsed package name.
Redirect responses now ensure unique values in the Vary header.
The vitest Playwright provider now allows any CHROME_BIN value.
Line endings are normalized when generating CSP hashes.
Assets are resolved correctly during i18n prerendering.
Package names are quoted conditionally based on host requirements when adding dependencies.
Preserves the exact requested version when adding a package.
The unit-test builder treats an empty browsers array as undefined.
Polyfills are bundled to preserve their execution order in the development server.
Improves header validation logic in SSR.
When the minimal option is enabled, schematics no longer add test dependencies.
Corrects dev dependency detection when running ng add.
Fixes a memory leak when serving applications with i18n.
Ensures group members are updated to the targeted version.
Formatting schematic changes now ignores unknown files.
The unit-test builder resolves style include paths relative to ng-package.json.
Non-relative imports are conditionally allowed with vi.mock.
The dev-server now normalizes allowedHosts.
Complex range specifiers are now quoted when passed to the package manager.
Prettier execution now enables the shell option on Windows.
Renamed files are now identified by their new path.
Scoped packages in Yarn Classic list output are now parsed correctly.
Absolute setup file paths are now resolved correctly in Vitest.
Addresses the Node.js deprecation DEP0190.
Prevents incorrect catch binding removal when downleveling for-await code.
Removes special characters from the jasmine-vitest report filename.
Removes a nonexistent link from the MCP response.
Corrects the VS Code MCP configuration generated for new projects.
Correctly spawns package managers on Windows.
Normalizes roots to POSIX to improve Windows compatibility.
Resolves test files correctly on Windows when using non-C drives.
Handles platform destruction during rendering.
Project targeting is corrected during Vitest debugging.
Non-prefixed requests are allowed when using SSR with a base href.
The status code is propagated to redirects.
Tests run when a compilation error is resolved.
The resolver now includes the browser condition for Vitest.
Well-known non-Angular URLs receive a leading slash.
The locale base href retains its leading slash.
The Jasmine-to-Vitest refactor now handles createSpyObj calls without a base name.
The Jasmine-to-Vitest migration improves the safety of transforming done callbacks.
Redirects no longer enter a loop with encoded query parameters.
Paths passed with --include are now normalized to POSIX format.
The migration now adds missing imports for lifecycle hooks, so migrated tests can reference those hooks.
The Jasmine-to-Vitest migration now handles jasmine.clock().mockDate() correctly.
The migration no longer sets esModuleInterop or moduleResolution when module is preserve.
The CLI now resolves dependencies correctly for the node modules directory check.
The Vitest runner now configures headless mode correctly per browser.
URL joining for prerender routes is now handled correctly.
The dev server now uses HTTP/1.1 when SSR is used with SSL.
Coverage paths now resolve correctly for JSDOM on Windows.
Redirects now handle X-Forwarded-Prefix and APP_BASE_HREF.
@angular/cli 2017 changes
Breaking changes 2
forceAuth is removed.
Unscoped credential parsing is removed.
Security 2
Angular SSR has a Server-Side Request Forgery (SSRF) flaw
Prevents a malicious URL from overriding the host.
Behavior and default changes 1
When resolving version ranges, deprecated versions are now used as a fallback if no non-deprecated version is found.
Tooling 2
Version 30 is now allowed for jest.
Version 30 is now allowed for jest-environment-jsdom.
Fixes and other changes 10
Common engine rendering options now allow all hosts to prevent validation errors.
Prevents removing @angular/localize when external packages are present.
Corrects the include configuration for spec files.
Locale handling in app-engine is improved.
Route matching for wildcard routes is improved.
Redirects from guards are now handled during prerendering.
The Angular locale data namespace is resolved correctly in esbuild.
Schematics now respect --force when a schematic contains host.create.
SSR now correctly handles routes with matrix parameters.
Server-side navigation now triggers a redirect.