Skip to content

Upgrading @angular/compiler 17 to 18

Breaking17.3.12 → 18.2.14Breaking47Security1Platform3Deprecated10New39Changed6Fixed236Other4

BreakingUpgrade verdict

39 breaking changes and 3 platform requirement changes and a security fix.

  • Server-side apps must now pass a bootstrap context into `bootstrapApplication` instead of relying on a shared global platform.
  • Tests using fakeAsync will now run any leftover timers when the test function finishes, unless you opt out.
  • A long-deprecated animation helper method is gone, so any code still calling it will stop working.
  • Two deprecated platform-check functions are removed, so code using them must be updated.
Top 5 of 53 that need code or config changes

Node.js requirement changed in 18.1.0-next.1: ^18.13.0 || >=20.9.0 → ^18.19.1 || ^20.11.1 || >=22.0.0.

Breaking39
Introduces BootstrapContext for server bootstrapping, removing reliance on a global platform injector.
BootstrapContextbootstrapApplicationgetPlatform()destroyPlatform()
fakeAsync now flushes pending timers at the end of the given function by default.
fakeAsync
Removes deprecated matchesElement from AnimationDriver.
AnimationDrivermatchesElement
Removes deprecated isPlatformWorkerApp and isPlatformWorkerUi APIs.
isPlatformWorkerAppisPlatformWorkerUi
Removes support for unassignable expressions in two-way bindings.
Removes deprecated transfer state APIs.
StateKeyTransferStatemakeStateKey
Removes deprecated Testability methods.
Testability
Removes the unused RESOURCE_CACHE_PROVIDER API from platform-browser-dynamic.
RESOURCE_CACHE_PROVIDER
Removes the deprecated platformDynamicServer API from platform-server.
platformDynamicServer
Removes the deprecated ServerTransferStateModule API from platform-server.
ServerTransferStateModule
Removes deprecated useAbsoluteUrl and baseUrl from PlatformConfig; provide an absolute url instead.
useAbsoluteUrlbaseUrlPlatformConfigurl
Removes legacy URL handling logic from platform-server.
ComponentFixture autoDetect no longer refreshes host view for dirty-less OnPush components.
ComponentFixtureautoDetectOnPushmarkForCheckChangeDetectionStrategy.Default
Removes Testability methods increasePendingRequestCount, decreasePendingRequestCount and getPendingRequestCount.
increasePendingRequestCountdecreasePendingRequestCountgetPendingRequestCount
HTTP transfer cache now prevents caching of requests requiring authorization by default; opt out with includeRequestsWithAuthHeaders.
withHttpTransferCacheincludeRequestsWithAuthHeaders
Removes deprecated StateKey, TransferState and makeStateKey from @angular/platform-browser; use them from @angular/core.
StateKeyTransferStatemakeStateKey@angular/platform-browser@angular/core
Removes unused RESOURCE_CACHE_PROVIDER APIs from @angular/platform-browser-dynamic.
RESOURCE_CACHE_PROVIDER
Removes deprecated platformDynamicServer; import @angular/compiler and use platformServer instead.
platformDynamicServerplatformServer@angular/compiler
Removes deprecated ServerTransferStateModule; TransferState can be used without providing this module.
ServerTransferStateModuleTransferState
Removes legacy Node.js URL parsing from ServerPlatformLocation, changing pathname and port handling.
ServerPlatformLocationpathnameport
Excludes authenticated HTTP requests from caching by default; opt out with includeRequestsWithAuthHeaders.
withHttpTransferCacheincludeRequestsWithAuthHeaders
Angular no longer ignores changes that happen outside the zone, so change detection runs for them.
provideZoneChangeDetectionNgZoneSchedulingMode.NgZoneOnlyBootstrapOptionsbootstrapApplicationbootstrapModule
Removes deprecated Testability methods increasePendingRequestCount, decreasePendingRequestCount and getPendingRequestCount.
increasePendingRequestCountdecreasePendingRequestCountgetPendingRequestCount
Redesigns the afterRender and afterNextRender phases API.
afterRenderafterNextRender
ComponentFixture.whenStable now matches ApplicationRef.isStable, including router navigations and HttpClient requests, and isStable is always asynchronous.
ComponentFixture.whenStableApplicationRef.isStableComponentFixture.isStableHttpTestingController.verify()HttpClientfixture.whenStable
Modifies EventType from an enum to an object.
EventType
Angular only supports writable expressions inside two-way bindings.
OnPush root views must be marked dirty for their host bindings to refresh.
OnPush
Change detection continues refreshing views attached to ApplicationRef still marked for check, which can cause infinite loops surfaced as NG0103.
ApplicationRefChangeDetectorRef.detectChangesNG0103
Removes the async test helper; use waitForAsync instead.
asyncwaitForAsync
Change detection timing with event or run coalescing in NgZone is now the first of setTimeout or requestAnimationFrame.
NgZonesetTimeoutrequestAnimationFrameafterNextRender
Newly created or reattached views marked for check during change detection are now guaranteed to refresh in the same cycle.
ExpressionChangedAfterItHasBeenCheckedError
Router guards can now return RedirectCommand for redirects in addition to UrlTree, requiring Route type adjustments.
RedirectCommandUrlTreeRoute
Allows Route.redirectTo to be a function in addition to a string, so code expecting only a string must be adjusted.
Route.redirectToRoute
Guard redirects via UrlTree now use replaceUrl when the initial navigation used replaceUrl; return a RedirectCommand to customize options.
UrlTreereplaceUrlNavigationBehaviorOptionsRedirectCommand
Providers for routed components come only from the route injector hierarchy and never inherit from RouterOutlet.
RouterOutletNgModuleproviders
Completes the removal of the deprecated async function; use waitForAsync instead.
asyncwaitForAsync
Angular ensures change detection runs even when state updates originate outside the zone, which may add change detection rounds in tests.
provideZoneChangeDetectionNgZoneSchedulingMode.NgZoneOnlyTestBedbootstrapApplicationBootstrapOptionsbootstrapModule
ComponentFixture.autoDetect now runs change detection within ApplicationRef.tick, changing refresh order in tests.
ComponentFixture.autoDetectApplicationRef.tick
Security1
Addresses Trusted Types violations in @angular/upgrade.
@angular/upgrade
Platform3
Adds support for TypeScript 5.5.
Drops support for TypeScript versions older than 5.4.
Angular no longer supports TypeScript versions older than 5.4.
Deprecated10
Deprecates the ignoreChangesOutsideZone option.
ignoreChangesOutsideZone
Adds back the phase flag option as a deprecated API.
Deprecates the Local Data API functions.
Deprecates the @Component.interpolation property.
@Component.interpolation
Deprecates HttpClientModule and related modules.
HttpClientModule
Deprecates common locale helper functions including getCurrencySymbol, getLocaleCurrencyCode, getLocaleDateFormat and related APIs.
getCurrencySymbolgetLocaleCurrencyCodegetLocaleCurrencyNamegetLocaleCurrencySymbolgetLocaleDateFormatgetLocaleDateTimeFormatgetLocaleDayNamesgetLocaleDayPeriods
Deprecates @Component.interpolation; use Angular's delimiters instead.
@Component.interpolation
Deprecates HttpClientModule, HttpClientXsrfModule and HttpClientJsonpModule, which can be replaced by provider functions.
HttpClientModuleHttpClientXsrfModuleHttpClientJsonpModule
Deprecates @Component.interpolation in favor of Angular's delimiters.
@Component.interpolation
Deprecates HttpClientModule and related modules in favor of provider functions.
HttpClientModuleHttpClientXsrfModuleHttpClientJsonpModule

Generated by DepDelta from published .d.ts files. Not mixed with prose notes.

  • removed: const enum BindingType
  • removed: const enum ParsedEventType
  • removed: interface R3DeferBlockMetadata
  • removed: interface R3DeferBlockTemplateDependency
  • removed: property R3ComponentMetadata.deferBlockDepsEmitMode: DeferBlockDepsEmitMode
  • removed: property R3ComponentMetadata.deferBlocks: Map<t.DeferredBlock, R3DeferBlockMetadata>
  • removed: property R3ComponentMetadata.deferrableDeclToImportDecl: Map<outputAst.Expression, outputAst.Expression>
  • removed: property R3ComponentMetadata.deferrableTypes: Map<string, { importPath: string; isDefaultImport: boolean }>
  • removed: property R3ComponentMetadata.useTemplatePipeline: boolean
  • removed: property R3DeferBlockMetadata.deps: R3DeferBlockTemplateDependency[]
  • removed: property R3DeferBlockMetadata.triggerElements: Map<t.DeferredTrigger, t.Element | null>
  • removed: property R3DeferBlockTemplateDependency.importPath: string | null
  • removed: property R3DeferBlockTemplateDependency.isDefaultImport: boolean
  • removed: property R3DeferBlockTemplateDependency.isDeferrable: boolean
  • removed: property R3DeferBlockTemplateDependency.symbolName: string
  • removed: property R3DeferBlockTemplateDependency.type: outputAst.WrappedNodeExpr<unknown>
  • removed: property R3HostMetadata.useTemplatePipeline: boolean
  • removed: static property R3Identifiers.InputFlags: outputAst.ExternalReference
  • changed: constructor ExternalReference(moduleName: string | null, name: string | null, runtime?: any) → constructor ExternalReference(moduleName: string | null, name: string | null, runtime?: any | null)
  • changed: constructor FunctionExpr(params: FnParam[], statements: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: string | null | undefined) → constructor FunctionExpr(params: FnParam[], statements: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: (string | null) | undefined)
  • changed: constructor MessageBundle(_htmlParser: HtmlParser, _implicitTags: string[], _implicitAttrs: { [k: string]: string[] }, _locale?: string | null) → constructor MessageBundle(_htmlParser: HtmlParser, _implicitTags: string[], _implicitAttrs: { [k: string]: string[] }, _locale?: string | null, _preserveWhitespace?: boolean)
  • changed: constructor TmplAstContent(selector: string, attributes: TmplAstTextAttribute[], sourceSpan: ParseSourceSpan, i18n?: I18nMeta_2 | undefined) → constructor TmplAstContent(selector: string, attributes: TmplAstTextAttribute[], children: TmplAstNode[], sourceSpan: ParseSourceSpan, i18n?: I18nMeta_2 | undefined)
  • changed: constructor TmplAstForLoopBlock(item: TmplAstVariable, expression: ASTWithSource, trackBy: ASTWithSource, trackKeywordSpan: ParseSourceSpan, contextVariables: ForLoopBlockContext, children: TmplAstNode[], empty: TmplAstForLoopBlockEmpty | null, sourceSpan: ParseSourceSpan, mainBlockSpan: ParseSourceSpan, startSourceSpan: ParseSourceSpan, endSourceSpan: ParseSourceSpan | null, nameSpan: ParseSourc… → constructor TmplAstForLoopBlock(item: TmplAstVariable, expression: ASTWithSource, trackBy: ASTWithSource, trackKeywordSpan: ParseSourceSpan, contextVariables: TmplAstVariable[], children: TmplAstNode[], empty: TmplAstForLoopBlockEmpty | null, sourceSpan: ParseSourceSpan, mainBlockSpan: ParseSourceSpan, startSourceSpan: ParseSourceSpan, endSourceSpan: ParseSourceSpan | null, nameSpan: ParseSourceS…
  • changed: function compileClassMetadata(metadata: R3ClassMetadata): outputAst.Expression → function compileClassMetadata(metadata: R3ClassMetadata): outputAst.InvokeFunctionExpr
  • changed: function compileComponentClassMetadata(metadata: R3ClassMetadata, deferrableTypes: Map<string, { importPath: string; isDefaultImport: boolean }> | null): outputAst.Expression → function compileComponentClassMetadata(metadata: R3ClassMetadata, dependencies: R3DeferPerComponentDependency[] | null): outputAst.Expression
  • changed: function makeBindingParser(interpolationConfig?: InterpolationConfig): BindingParser → function makeBindingParser(interpolationConfig?: InterpolationConfig, allowInvalidAssignmentEvents?: boolean): BindingParser
  • changed: member LexerTokenType.EOF = 29 → member LexerTokenType.EOF = 33
  • changed: method BoundTarget.getDefinitionNodeOfSymbol(symbol: TmplAstReference | TmplAstVariable): ScopedNode | null → method BoundTarget.getDefinitionNodeOfSymbol(symbol: TemplateEntity): ScopedNode | null
  • changed: method BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TmplAstReference | TmplAstVariable> → method BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TemplateEntity>
  • changed: method BoundTarget.getExpressionTarget(expr: AST): TmplAstReference | TmplAstVariable | null → method BoundTarget.getExpressionTarget(expr: AST): TemplateEntity | null
  • changed: method ConstantPool.getSharedFunctionReference(fn: outputAst.FunctionExpr | outputAst.ArrowFunctionExpr, prefix: string, useUniqueName?: boolean): outputAst.Expression → method ConstantPool.getSharedFunctionReference(fn: outputAst.Expression, prefix: string, useUniqueName?: boolean): outputAst.Expression
  • changed: method MessageBundle.updateFromTemplate(html: string, url: string, interpolationConfig: InterpolationConfig): ParseError[] → method MessageBundle.updateFromTemplate(source: string, url: string, interpolationConfig: InterpolationConfig): ParseError[]
  • changed: method R3BoundTarget.getDefinitionNodeOfSymbol(symbol: TmplAstReference | TmplAstVariable): ScopedNode | null → method R3BoundTarget.getDefinitionNodeOfSymbol(symbol: TemplateEntity): ScopedNode | null
  • changed: method R3BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TmplAstReference | TmplAstVariable> → method R3BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TemplateEntity>
  • changed: method R3BoundTarget.getExpressionTarget(expr: AST): TmplAstReference | TmplAstVariable | null → method R3BoundTarget.getExpressionTarget(expr: AST): TemplateEntity | null
  • changed: property ExternalReference.runtime?: any → property ExternalReference.runtime?: any | null
  • changed: property FunctionExpr.name?: string | null | undefined → property FunctionExpr.name?: (string | null) | undefined
  • changed: property TmplAstForLoopBlock.contextVariables: ForLoopBlockContext → property TmplAstForLoopBlock.contextVariables: TmplAstVariable[]
  • changed: type LiteralMapKey = { key: string; quoted: boolean } → type LiteralMapKey = { key: string; quoted: boolean; isShorthandInitialized?: boolean }
  • added: class LetDeclaration implements BaseNode
  • added: class TmplAstLetDeclaration implements TmplAstNode
  • added: constructor LetDeclaration(name: string, value: string, sourceSpan: ParseSourceSpan, nameSpan: ParseSourceSpan, valueSpan: ParseSourceSpan)
  • added: constructor TmplAstLetDeclaration(name: string, value: AST, sourceSpan: ParseSourceSpan, nameSpan: ParseSourceSpan, valueSpan: ParseSourceSpan)
  • added: constructor Xmb(preservePlaceholders?: boolean)
  • added: enum BindingType
  • added: enum ParsedEventType
  • added: function compileComponentDeclareClassMetadata(metadata: R3ClassMetadata, dependencies: R3DeferPerComponentDependency[] | null): outputAst.Expression
  • added: function compileDeferResolverFunction(meta: R3DeferResolverFunctionMetadata): outputAst.ArrowFunctionExpr
  • added: function compileOpaqueAsyncClassMetadata(metadata: R3ClassMetadata, deferResolver: outputAst.Expression, deferredDependencyNames: string[]): outputAst.Expression
  • added: function findMatchingDirectivesAndPipes(template: string, directiveSelectors: string[]): { directives: { regular: string[]; deferCandidates: string[] }; pipes: { regular: string[]; deferCandidates: string[] } }
  • added: interface R3DeclareClassMetadataAsync extends R3PartialDeclaration
  • added: interface R3DeferPerBlockDependency
  • added: interface R3DeferPerComponentDependency
  • added: member LexerTokenType.INCOMPLETE_LET = 32
  • added: member LexerTokenType.LET_END = 31
  • added: member LexerTokenType.LET_START = 29
  • added: member LexerTokenType.LET_VALUE = 30
  • added: method LetDeclaration.visit(visitor: Visitor, context: any): any
  • added: method RecursiveVisitor.visitLetDeclaration(decl: LetDeclaration, context: any): void
  • added: method TmplAstLetDeclaration.visit<Result>(visitor: TmplAstVisitor<Result>): Result
  • added: method TmplAstRecursiveVisitor.visitLetDeclaration(decl: TmplAstLetDeclaration): void
  • added: method TmplAstVisitor.visitLetDeclaration(decl: TmplAstLetDeclaration): Result
  • added: method Visitor.visitLetDeclaration(decl: LetDeclaration, context: any): any
  • added: property LetDeclaration.name: string
  • added: property LetDeclaration.sourceSpan: ParseSourceSpan
  • added: property LetDeclaration.value: string
  • added: property LetDeclaration.valueSpan: ParseSourceSpan
  • added: property ParseTemplateOptions.allowInvalidAssignmentEvents?: boolean
  • added: property ParseTemplateOptions.enableLetSyntax?: boolean
  • added: property ParseTemplateOptions.preserveSignificantWhitespace?: boolean
  • added: property R3ComponentMetadata.defer: R3ComponentDeferMetadata
  • added: property R3DeclareClassMetadataAsync.resolveDeferredDeps: outputAst.Expression
  • added: property R3DeclareClassMetadataAsync.resolveMetadata: outputAst.Expression
  • added: property R3DeclareComponentMetadata.deferBlockDependencies?: outputAst.Expression[]
  • added: property R3DeferPerBlockDependency.importPath: string | null
  • added: property R3DeferPerBlockDependency.isDefaultImport: boolean
  • added: property R3DeferPerBlockDependency.isDeferrable: boolean
  • added: property R3DeferPerBlockDependency.symbolName: string
  • added: property R3DeferPerBlockDependency.typeReference: outputAst.Expression
  • added: property R3DeferPerComponentDependency.importPath: string
  • added: property R3DeferPerComponentDependency.isDefaultImport: boolean
  • added: property R3DeferPerComponentDependency.symbolName: string
  • added: property TmplAstContent.children: TmplAstNode[]
  • added: property TmplAstLetDeclaration.name: string
  • added: property TmplAstLetDeclaration.nameSpan: ParseSourceSpan
  • added: property TmplAstLetDeclaration.sourceSpan: ParseSourceSpan
  • added: property TmplAstLetDeclaration.value: AST
  • added: property TmplAstLetDeclaration.valueSpan: ParseSourceSpan
  • added: readonly property LetDeclaration.nameSpan: ParseSourceSpan
  • added: static property R3Identifiers.declareClassMetadataAsync: outputAst.ExternalReference
  • added: static property R3Identifiers.declareLet: outputAst.ExternalReference
  • added: static property R3Identifiers.readContextLet: outputAst.ExternalReference
  • added: static property R3Identifiers.storeLet: outputAst.ExternalReference
  • added: type R3ComponentDeferMetadata = { mode: DeferBlockDepsEmitMode.PerBlock; blocks: Map<t.DeferredBlock, outputAst.Expression | null> } | { mode: DeferBlockDepsEmitMode.PerComponent; dependencie…
  • added: type R3DeferResolverFunctionMetadata = { mode: DeferBlockDepsEmitMode.PerBlock; dependencies: R3DeferPerBlockDependency[] } | { mode: DeferBlockDepsEmitMode.PerComponent; dependencies: R3DeferPerCom…
  • added: type TemplateEntity = TmplAstReference | TmplAstVariable | TmplAstLetDeclaration