Migrate AngularJS components incrementally
Migrating AngularJS to Angular succeeds when you move one component at a time. This workflow is the per-component loop: pick a leaf, rewrite it as an Angular component, bridge it with downgrade/upgrade, verify it renders identically, and repeat until the AngularJS surface is gone.
Last verified · Updated May 22, 2026
Incremental migration is the loop that makes the AngularJS-to-Angular move safe: with ngUpgrade in place, you pick one leaf component, rewrite it in Angular with TypeScript, bridge it via downgradeComponent, verify it renders identically, and repeat. Each iteration is small enough to review and revert.
Migrate components that have no AngularJS children first. Working bottom-up means each rewrite depends only on already-migrated or interop-bridged pieces, which keeps every step independently verifiable.
The per-component loop
- Pick a leaf component with the fewest AngularJS dependencies.
- Rewrite its controller/$scope as a typed Angular component with @Input/@Output.
- Bridge it: downgradeComponent to render in AngularJS, or upgradeComponent to host a remaining AngularJS directive.
- Migrate any service it depends on to @Injectable (downgradeInjectable if AngularJS still needs it).
- Verify it renders identically, run the build and its tests, then commit and repeat.
Diagnostic commands
# Find AngularJS leaf components to migrate next (directives/controllers with no nested custom elements)$ grep -rEl "\.controller\(|\.directive\(" src/ | head# After each rewrite, verify the hybrid app still builds and the component's tests pass$ ng build && ng test --watch=falseMigrate a single AngularJS component to Angular. I'll name the component or you can pick the lowest-risk leaf. Rewrite its controller/$scope into a typed Angular component with @Input/@Output, bridge it with downgradeComponent so the AngularJS template still renders it, and migrate only the services this component needs. Run ng build and the component's tests, then report before suggesting the next component. Do not migrate more than one component in this step.
Safety: One component per iteration. Never bundle multiple components or unrelated refactors into a single change.
Per-iteration checklist
- Exactly one component was migrated this iteration
- $scope state was rewritten to typed inputs, not copied verbatim
- downgrade/upgrade bridging is correct and removed once both sides are Angular
- ng build and the component's tests pass with the hybrid app present
Escalation checklist
- A component cannot be isolated as a leaf without first migrating shared state
- A third-party AngularJS dependency has no modern Angular equivalent
- Change-detection/digest boundary issues appear at the interop seam
Related migration paths
Official sources
Backs the breaking-change and migration-step claims.