skip to content

Upgrades & Legacy Code

Keeping an Angular codebase current: the release and support calendar, the core schematics that modernize code, and the path off AngularJS. Interviewers ask how you would run a multi-major upgrade.

part ofAngularoverview, primer and where to startread it →
on this pageshow

explore

questions

16

What are the main differences between AngularJS (1.x) and Angular, and is AngularJS still supported?

level: juniorimportance: must knowfreq 58%

answer

  1. same team, different framework
  2. controllers and scope vs components
  3. digest loop vs view-tree check
  4. JavaScript vs TypeScript
  5. support ended early 2022

basics

~20 s

AngularJS (1.x) is a JavaScript framework built on controllers, $scope and a digest loop of watchers; Angular is a TypeScript rewrite built on components, hierarchical dependency injection and top-down change detection. AngularJS support ended in January 2022.

solid answer

~50 s

AngularJS is the name for all 1.x versions; Angular (2 and later) is a **complete rewrite**, not an upgrade path you can `npm update` across. AngularJS apps are built from **controllers** that put data on a **`$scope`**, **directives**, and string-named services, and it keeps the page in sync with a **digest cycle** that re-runs watchers until nothing changes. Angular is written in **TypeScript** and built from **components** with templates, services in **hierarchical injectors** resolved by type or token, and **change detection** that checks the component tree from the top down with one-way data flow. Templates changed too: `ng-*` attributes became `[property]` and `(event)` bindings and, today, `@if`/`@for` blocks. AngularJS reached **end of support in January 2022**, so it gets no security fixes; the `@angular/upgrade` package exists to run both side by side while you migrate.

go deeper

for a junior

Recall the headline differences: TypeScript and components in Angular, controllers, $scope and the digest cycle in AngularJS, and that AngularJS support ended in January 2022.

for a middle

Explain why the rewrite happened: digest cost, scope inheritance, string-based DI, and how one-way data flow and a single tree check address them.

for a senior

Discuss what an unsupported AngularJS app means in production and which migration route fits a given codebase.

for a principal

Weigh rewrite versus hybrid for a large AngularJS estate, including the cost of running two frameworks for months.

"AngularJS" and "Angular" share a team, a name and some vocabulary, which is exactly why interviewers ask how they differ. The short version: Angular is not a newer AngularJS, it is a different framework. ## Naming and status - **AngularJS** is the name for every **1.x** version. - **Angular** is everything from version 2 onwards; v22 is current in 2026. - **AngularJS reached end of support in January 2022.** It receives no fixes, including security fixes. - There is no in-place update from one to the other. The official route is a **hybrid app** with `@angular/upgrade`, which is itself in maintenance mode, taking only security fixes. ## The building blocks | Concern | AngularJS (1.x) | Angular | | :-- | :-- | :-- | | Language | JavaScript | TypeScript | | UI unit | Controllers plus templates, directives; `.component()` added later in 1.x | Components (a class with `@Component` and a template), directives, pipes | | Data for the view | Properties on a `$scope` object, often inherited from parent scopes | Fields and signals on the component class | | Data flow | Two-way binding by default (`ng-model` and directive bindings) | One-way by default: `[property]` in, `(event)` out; two-way is opt-in (`[(...)]`, `model()`) | | Keeping the view in sync | **Digest cycle**: re-run all watchers until values stop changing | **Change detection**: check the component tree top-down, then stop | | Dependency injection | Services looked up by string name; array annotations to survive minification | Hierarchical injectors; tokens are classes or `InjectionToken`s; `inject()` | | Modules | `angular.module('app', [...])` for registration | Standalone components by default since v19; `NgModule` still supported | | Templates | `ng-if`, `ng-repeat`, `ng-click`, `{{ }}` | `@if`, `@for`, `(click)`, `[prop]`, `{{ }}`, compiled ahead of time | ## Why the rewrite happened Three limits of AngularJS drove it: 1. **Performance of the digest cycle.** Every binding adds a watcher, and a digest runs all of them, repeatedly, until the page is stable. Large screens with thousands of bindings became slow, and two-way bindings could trigger cascades of extra passes. 2. **Scope inheritance was hard to reason about.** Nested `$scope`s inherited prototypally, so a child could read, shadow or accidentally write a parent's value. 3. **Tooling and scale.** String-named DI, runtime template compilation and plain JavaScript made large codebases hard to refactor and optimise. Angular answered with ahead-of-time compiled templates, TypeScript, one-way data flow, and a change-detection pass that walks the component tree once per cycle. ## What stayed recognisable - **Dependency injection** as the core design idea, now hierarchical and type-based. - **Declarative templates** with `{{ }}` interpolation. - **Directives** as a way to add behaviour to elements. - **Services** as singletons holding shared logic. This familiarity is why hybrid migrations work at all: the concepts map, even though the APIs do not. ## What interviewers listen for - Saying "Angular 2 was an upgrade of AngularJS" misses that it was a rewrite. - Describing Angular's change detection as "a digest loop" imports the AngularJS model: Angular checks the tree once, and in development mode a second verification pass throws `ExpressionChangedAfterItHasBeenCheckedError` (NG0100) instead of looping. - Treating AngularJS as merely "old but fine" ignores that since January 2022 it gets no security patches. ## Migration options in one line each - **Rewrite**: build the Angular app separately and switch over; clean, but a long freeze on the old app. - **Hybrid**: run both with `@angular/upgrade` and move one screen or service at a time. - **Replace gradually at the route level**: serve some routes from a new app; simpler plumbing, but two apps to operate. Which one fits depends on the app's size and test coverage; the hybrid route is the one Angular provides tools for.

  • Can you update an AngularJS app to Angular with a package update?
    No. Angular is a rewrite with a different component model, change detection and DI, so there is no in-place update. The supported route is a hybrid app built with @angular/upgrade, where both frameworks run together and code moves over piece by piece, or a separate rewrite.
  • Why does AngularJS need $scope.$apply() and Angular does not need an equivalent in most code?
    AngularJS only runs a digest when something inside its world triggers one, so changes from outside, such as a third-party callback, need $apply to start a digest. Angular schedules change detection itself, through zone.js in zone-based apps or through notifications such as signal writes, events and markForCheck in zoneless apps.
  • What happens to security fixes for an app still on AngularJS today?
    There are none from the framework: AngularJS reached end of support in January 2022. Any newly found vulnerability stays unpatched unless the team patches or mitigates it itself, which is a strong argument for migrating or isolating the app.

saying these in an interview costs you the question

  • Angular 2 was an incremental upgrade of AngularJS.
  • Angular still uses a digest loop that repeats until values settle.
  • Angular data binding is two-way by default, just like AngularJS.
  • AngularJS is old but still receives security patches.
  • Both frameworks resolve services by string name.
open as a page

What does Angular's control-flow migration change in your templates, and what does it leave for you to review?

level: middleimportance: must knowfreq 55%

basics

~20 s

Angular's control-flow migration rewrites *ngIf, *ngFor and *ngSwitch into @if, @for and @switch and drops the now-unused directive imports. It leaves review work: identity tracking where no trackBy existed, kept ng-templates, CommonModule still imported, and templates it could not parse.

open as a page

Since Angular v22, how often does a new major version ship, and how long is each major supported?

level: middleimportance: must knowfreq 58%

basics

~20 s

Since v22 Angular ships a major roughly every 12 months, with 4-6 minors in between. Each major is supported for about 24 months: 12 months active, then 12 months of LTS that only takes critical and security fixes.

open as a page

You own a v15-era Angular codebase now updated to v22; in what order would you run the modernization schematics, feature by feature, and why?

level: seniorimportance: must knowfreq 46%

basics

~20 s

Run the optional schematics after the version update, one feature folder at a time: control flow, then the three standalone modes, then inject(), then the signal input, output and query migrations, and self-closing tags last, testing between each.

open as a page

Your Angular app is on v20 while v22 is current; how would you plan the upgrade, and why not jump straight to v22?

level: seniorimportance: must knowfreq 52%

basics

~20 s

Upgrade one major at a time, v20 to v21 then v21 to v22, because Angular's policy supports updates only within one major and ng update refuses multi-major jumps. v20's LTS ends 2026-11-28, so plan both hops before then.

open as a page

How does AngularJS's digest cycle differ from Angular's change detection, and why did the difference matter for performance?

level: middleimportance: should knowfreq 45%

basics

~20 s

AngularJS's digest re-runs every watcher and repeats until no value changes. Angular checks its component tree once, top-down, with one-way data flow, and in development mode throws an error instead of looping when a checked value changes.

open as a page

In an @angular/upgrade hybrid app, what do downgradeComponent, downgradeInjectable and UpgradeComponent each let you do?

level: middleimportance: should knowfreq 40%

basics

~20 s

downgradeComponent wraps an Angular component as an AngularJS directive, downgradeInjectable exposes an Angular service to AngularJS's injector, and UpgradeComponent is a base class for an Angular directive that wraps an AngularJS component. AngularJS services are upgraded with a plain Angular provider.

open as a page

How does Angular's standalone migration convert an NgModule-based app, and why must its three modes run in order?

level: middleimportance: should knowfreq 45%

basics

~20 s

Angular's standalone migration runs in three passes: convert components, directives and pipes to standalone, prune NgModules that became empty, then switch bootstrapModule to bootstrapApplication. Each pass relies on the previous one, and each needs a build check between runs.

open as a page

When you update to Angular v22, what does the Eager change-detection migration do to existing components, and why?

level: middleimportance: should knowfreq 40%

basics

~10 s

Because v22 made OnPush the default, the v22 update migration adds changeDetection: ChangeDetectionStrategy.Eager to every component that set no value and renames explicit Default to Eager, so existing components behave exactly as before.

open as a page

What does Angular's deprecation policy guarantee between an API being marked deprecated and it being removed?

level: middleimportance: should knowfreq 42%

basics

~20 s

A deprecated Angular API is announced in the changelog with a replacement, tagged @deprecated, and kept for at least the next major (about 12 months). Removal happens only in a major; meanwhile it gets only critical and security fixes.

open as a page

You are migrating a large AngularJS app to Angular one screen at a time with UpgradeModule; how do you bootstrap and sequence it, and what pitfalls do you expect?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Bootstrap Angular first and let UpgradeModule bootstrap AngularJS in ngDoBootstrap, so AngularJS owns the root. Move shared services first, then screens from leaf components upward, bridging each boundary. Expect extra change-detection cycles, unsupported directive features, and a maintenance-mode package.

open as a page

Why does Angular's signal-input migration skip some @Input fields, and how do you deal with the ones it leaves?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Angular's signal-input migration only converts inputs it can prove safe; fields written to, accessor inputs, inherited conflicts, spyOn targets, @HostBinding use or template narrowing are skipped. Use --insert-todos to see why, then fix by hand or opt into --best-effort-mode.

open as a page

How would you set an Angular upgrade policy across many apps and shared libraries so that none falls out of support?

level: principalimportance: should knowfreq 30%

basics

~20 s

Treat Angular's yearly major as a fixed annual upgrade budget, keep every app within one major of current so it stays supported, and choose between lockstep upgrades and per-app upgrades with shared libraries spanning two majors.

open as a page

What does Angular's self-closing-tags migration change in templates, and why does it leave an empty <div></div> alone?

level: juniorimportance: nice to knowfreq 18%

basics

~10 s

Angular's self-closing-tags migration rewrites empty component and custom-element tags such as <app-spinner></app-spinner> into <app-spinner />. It skips standard HTML elements like <div>, which cannot self-close in HTML, and any tag with real content.

open as a page

In Angular, how do developer preview and experimental APIs differ from stable ones, and would you ship them to production?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

Developer preview APIs in Angular are complete and polished but not yet stabilised; experimental APIs may change heavily or never stabilise. Neither is covered by semver or the deprecation policy, so either can change even in a patch release.

open as a page

In @angular/upgrade, how does downgradeModule() differ from UpgradeModule, and when would you choose it?

level: seniorimportance: nice to knowfreq 22%

basics

~20 s

downgradeModule() bootstraps the Angular part lazily, when a downgraded component is first needed, and does not tie change detection to AngularJS's digest. It suits AngularJS-led apps with a few heavy Angular screens, at the cost of manual cross-framework notification.

open as a page