angular/angular
Architecture
Angular ships several distinct artifacts from a single monorepo: the @angular/* runtime packages on npm, the angular.dev documentation site, the Angular DevTools browser extension, and the framework's own development app. Bazel is the build orchestrator across all of them, with pnpm workspaces handling JavaScript dependency resolution.
High-level layers
graph TD
subgraph Authoring
Templates["Templates<br/>(.html, inline)"]
TS["TypeScript classes<br/>@Component / @Directive / @Pipe"]
end
subgraph CompileTime["Compile time (ngtsc)"]
NgTsc["packages/compiler-cli/src/ngtsc<br/>Annotation handlers"]
NgCompiler["packages/compiler<br/>Template parser → IR → output"]
end
subgraph RunTime["Runtime (Ivy)"]
Core["packages/core/src/render3<br/>LView, TView, instructions"]
DI["packages/core/src/di<br/>Hierarchical injectors"]
CD["Change detection<br/>(zoneless capable)"]
Signals["@angular/core/primitives/signals<br/>Reactivity primitives"]
end
subgraph Platform["Platform"]
PB["platform-browser<br/>(DOM renderer)"]
PS["platform-server<br/>(SSR renderer + domino)"]
end
subgraph Domain["Domain libraries"]
Common["@angular/common<br/>(NgIf, NgFor, NgForOf, HttpClient)"]
Router["@angular/router"]
Forms["@angular/forms<br/>(reactive + signal forms)"]
Animations["@angular/animations"]
Elements["@angular/elements"]
end
Templates --> NgTsc
TS --> NgTsc
NgTsc --> NgCompiler
NgCompiler --> Core
Core --> CD
Core --> DI
Core --> Signals
CD --> PB
CD --> PS
Domain --> CoreThe compile-time pipeline (ngtsc)
ngtsc is the TypeScript compiler plugin Angular ships in packages/compiler-cli/src/ngtsc. It is a TypeScript transformer that:
- Reads each source file via
ts.Program. - Discovers Angular decorators (
@Component,@Directive,@Pipe,@Injectable,@NgModule) using annotation handlers underngtsc/annotations/. - Resolves component templates (inline or
templateUrl) and stylesheets viangtsc/resource. - Hands templates to the
@angular/compilerparser, which produces the template AST and the intermediate representation (IR) defined inpackages/compiler/src/render3/view. - Emits Ivy "definition" output: a
ɵcmpstatic field on the component class that contains the compiled template instructions, plus diagnostics for type-checked templates. - Optionally writes a
.d.tsaugmentation so downstream consumers see the public API.
Two related entry points live next to it:
packages/compiler-cli/src/main.ts— thengcbinary used bybazel/CLI builds.packages/compiler-cli/linker— the partial-compilation linker that finishes Ivy compilation for libraries shipped in "partial" form on npm.
Type checking of templates is performed by the typecheck subsystem (ngtsc/typecheck), which generates "type check blocks" (TCBs) — synthetic TypeScript statements that mirror template binding semantics so that tsc can produce ordinary diagnostics.
The Ivy runtime
packages/core/src/render3 is the Ivy runtime: instruction-based, tree-shakable, and the engine since Angular 9. The two key data structures are LView and TView:
TView(template view, inrender3/interfaces/view.ts) — the static, compile-time-derived blueprint shared across all instances of a component.LView— the per-instance live array containing component context, bindings, child views, and DOM references.
A compiled template is a function over LView that calls instructions like ɵɵelementStart, ɵɵproperty, ɵɵtemplate, ɵɵtext, ɵɵlistener, etc. The instruction set lives in packages/core/src/render3/instructions.
sequenceDiagram participant Bootstrap as bootstrapApplication participant Core as @angular/core participant Tmpl as Compiled template fn participant DOM Bootstrap->>Core: createComponent(rootDef) Core->>Core: allocate LView, link to TView Core->>Tmpl: render(LView, RenderFlags.Create) Tmpl->>DOM: ɵɵelementStart, ɵɵtext, ... Core->>Tmpl: render(LView, RenderFlags.Update) Tmpl->>DOM: ɵɵproperty(value)
Change detection drives subsequent updates: markForCheck schedules a tick, the scheduler runs refreshView over each dirty LView, and instructions in RenderFlags.Update mode re-evaluate bindings. Signals add a finer-grained reactive layer in packages/core/primitives/signals: components that read signals automatically subscribe via a ReactiveLViewConsumer and are scheduled when the signal changes, even in zoneless apps.
Dependency injection
Hierarchical injectors are implemented in packages/core/src/di with the runtime hot path in render3/di.ts. Each LView carries a bloom-filter–accelerated lookup so directive injection at template instantiation time stays O(1) on average. Provider scopes — module, environment, component, and platform — are layered as separate injector trees that delegate upward.
Platform abstraction
The DOM is abstracted behind a Renderer2 interface so that the same template instructions can run on different platforms:
@angular/platform-browser— renders into the real DOM and registers event listeners directly.@angular/platform-server— renders intodomino, serializes the DOM to HTML for SSR/SSG, and emits hydration annotations consumed by the client at boot.
Hydration (packages/core/src/hydration) reuses the SSR-produced DOM at boot time instead of destroying and re-creating it, including support for incremental hydration of deferred views.
Build orchestration: Bazel + pnpm
Bazel is the source of truth for build graphs. Top-level BUILD.bazel files in each package describe TypeScript libraries (ng_module), tests (ng_web_test_suite, nodejs_test), and bundles. pnpm-workspace.yaml enumerates the JavaScript projects so that workspace-relative @angular/* imports resolve directly to the source. The tools/defaults.bzl file centralizes Bazel macro defaults used across the repo.
graph LR pnpm["pnpm install"] --> NodeModules["node_modules<br/>(pnpm content-addressable store)"] NodeModules --> Bazel["bazelisk build/test"] Bazel --> NgPackage["@angular/* dist/<br/>(packages/*/npm_package)"] Bazel --> Adev["adev:build<br/>angular.dev static site"] Bazel --> Devtools["devtools shell-browser<br/>(Chrome/Firefox extension)"]
CI runs in GitHub Actions (.github/workflows). Pull requests trigger pr.yml and the cross-cutting ci.yml, plus dedicated workflows for the documentation preview deploy (adev-preview-build.yml, adev-preview-deploy.yml), benchmarks (benchmark-compare.yml, perf.yml), and merge automation (merge-ready-status.yml, assistant-to-the-branch-manager.yml).
Public API surface
Each package's exported API is captured in goldens/public-api/ as .d.ts snapshots. Adding or changing a public export requires running pnpm public-api:update and including the diff in the PR. This catches accidental breaks without a separate code review pass.
Where to learn more
- The Ivy instruction set:
systems/ivy-runtime - The template compiler in detail:
systems/template-compiler - Hydration:
systems/hydration - The reactivity model:
features/signals
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.