AngularJS → Angular
AngularJS is end-of-life, so this migration is urgent. ngUpgrade lets AngularJS and Angular run in the same hybrid app, so you rewrite component by component instead of doing a risky big-bang rewrite — adopting TypeScript and Angular's router as you go.
Last verified · Updated May 22, 2026
AngularJS is end-of-life with no security patches, so this migration is urgent. The supported approach is ngUpgrade's hybrid app: AngularJS and modern Angular bootstrap together, and you migrate one component at a time using downgradeComponent / downgradeInjectable while rewriting $scope and controllers into Angular components.
⛔ AngularJS is end-of-life
AngularJS LTS ended on December 31, 2021 — there are no further security patches. Treat this migration as a security obligation, not just a modernization, and keep an active plan even while the hybrid app is in place.
Why a hybrid app, not a rewrite
ngUpgrade's UpgradeModule lets the AngularJS injector and the Angular injector coexist in one running application. You bootstrap Angular, then bootstrap AngularJS through UpgradeModule, and the two share the DOM. That lets you ship a partly-migrated app continuously instead of holding a long-lived rewrite branch that drifts from production.
How the incremental migration works
- Stand up a hybrid app with UpgradeModule so AngularJS and Angular bootstrap together.
- Expose Angular components into AngularJS templates with downgradeComponent, and Angular services with downgradeInjectable.
- Use upgradeComponent to render an AngularJS directive inside an Angular component when you must migrate top-down.
- Rewrite $scope and controllers into Angular components with @Input/@Output and explicit TypeScript types.
- Migrate the router last: move from ngRoute/ui-router to @angular/router once the views it points at are Angular components.
AngularJS to Angular concept map
| AngularJS | Angular |
|---|---|
| angular.module(...).controller | @Component class |
| $scope properties | Component fields + @Input/@Output |
| .factory / .service | @Injectable() service |
| ng-repeat / ng-if | @for / @if (or *ngFor / *ngIf) |
| $http | HttpClient |
| $routeProvider / ui-router | @angular/router (Routes) |
Hybrid interop
Downgrade an Angular component for use in AngularJS templates
// Render a modern Angular component inside AngularJS during the hybrid phase
import { downgradeComponent } from '@angular/upgrade/static';
import { UserCardComponent } from './user-card.component';
angular
.module('legacyApp')
.directive(
'userCard',
downgradeComponent({ component: UserCardComponent }) as angular.IDirectiveFactory,
);Per-component PR review checklist
- The rewritten Angular component renders identically to the AngularJS original
- downgrade/upgrade wiring is removed once both sides are Angular
- $scope state was rewritten to typed component fields, not copied verbatim
- Shared services were migrated to @Injectable before their last consumer
- ng build and the component's tests pass with the hybrid app present
Rollback strategy
- Migrate one component per commit so any single regression is a one-line revert.
- Keep the AngularJS version of a view until its Angular replacement is verified in a build.
- If a component blocks on a third-party AngularJS dependency, leave it downgraded and continue with others.
Related paths
- Angular 16 to Angular 18 Migration Guide — Upgrade path to same target
- Migrate AngularJS to React — Adjacent migration
- Migrate AngularJS Components Incrementally — Related path
Official sources
- Upgrading from AngularJS to Angular (ngUpgrade) — angular.dev (reliability 98%)
- Angular Update Guide — angular.dev (reliability 98%)
Copy-ready AI prompts
Structured prompts for an AI coding assistant. Inspect first, then execute incrementally, and keep a human in the review loop.
Repo inspection: Repo inspection prompt
You are helping migrate an Angular codebase from AngularJS to modern Angular.
Do not edit files yet. First inspect the repository and report:
1. The exact @angular/core and @angular/cli versions in package.json and the lockfile (or the angular.js version for AngularJS apps).
2. The architecture: NgModules vs standalone components, the router in use ($routeProvider, ui-router, or @angular/router), and any $scope/controller code still present.
3. Components, services, and directives grouped by complexity so a migration order can be planned.
4. Third-party libraries and whether they have versions compatible with the target.
5. Build, lint, and test commands (ng build, ng test, ng lint, or the legacy toolchain).
Return: a migration risk summary, the modules/components most likely to break, a suggested incremental order, the commands to run before editing, and any questions that need human confirmation.Safety: Inspection only. The agent must not modify files in this step.
Works with Claude Code, Cursor, GitHub Copilot.
Migration execution: Migration execution prompt
Migrate this codebase from AngularJS to modern Angular, one component or concern at a time.
Work incrementally and pause for review after each unit: stand up the hybrid/bridge layer first, then migrate the lowest-risk leaf component, rewrite its template and state, wire it back into the host app, and verify it renders identically before moving on. Convert services and routing only after the components that depend on them are migrated.
After each step run the project's build, lint, and tests, and report results before continuing. Do not refactor unrelated code or bundle multiple components into one change.Safety: Apply changes incrementally and keep each step reviewable. Never bundle unrelated refactors or migrate multiple components at once.
Works with Claude Code, Cursor, GitHub Copilot.
Test plan
Commands
ng buildng lintng test --watch=falsenpx playwright test
Manual checks
- For each migrated component, compare rendered output and behavior against the AngularJS original.
- Exercise interop boundaries: AngularJS templates using downgraded components and Angular components hosting upgraded directives.
- Verify routing still reaches every view during the hybrid phase.
Regression risks
- Digest/zone boundary issues where AngularJS $digest and Angular change detection interact.
- Untyped $scope state copied verbatim instead of being rewritten to typed inputs.
- Third-party AngularJS libraries with no modern Angular equivalent.
Acceptance criteria
- Every targeted view is served by modern Angular and the AngularJS equivalent is removed.
- ng build, lint, unit, and e2e tests pass.
- No AngularJS modules or UpgradeModule wiring remain once migration completes.