Angular Core (packages/core) Mental Model
This document outlines the architecture and mental model for packages/core, the heart of the Angular framework.
1. High-Level Architecture
packages/core contains the runtime logic for Angular. Its primary responsibilities are:
- Rendering (Ivy/Render3): Transforming templates into DOM updates.
- Dependency Injection (DI): Managing object creation and lifetime.
- Change Detection: Synchronizing the model with the view.
- Reactivity: Signals and Zone.js integration.
2. Rendering Engine (Ivy / Render3)
The rendering engine (located in packages/core/src/render3) uses an instruction-based approach.
Key Concepts
Instructions: The Angular compiler transforms templates into a sequence of instruction calls (e.g., ɵɵelementStart, ɵɵtext, ɵɵproperty). These instructions are executed at runtime to create and update the view.
- Location:
packages/core/src/render3/instructions
LView (Logical View): An array containing the state of a specific view instance. It holds:
- DOM nodes (
RElement, RText).
- Binding values (for change detection).
- Directive/Component instances.
- Context:
packages/core/src/render3/interfaces/view.ts
TView (Template View): An array containing the static structure of a view. It is shared across all instances (LViews) of the same component/template. It holds:
- Property names for bindings.
- Node relationship information.
- Compiled directive definitions.
- Context:
packages/core/src/render3/interfaces/view.ts
Memory Layout: LView and TView are parallel arrays. Index i in LView corresponds to metadata at index i in TView.
HEADER: Fixed size, contains context (Parent, Host, etc.).
DECLS: Static nodes (elements, text, pipes).
VARS: Binding values.
EXPANDO: Dynamic data (host bindings, injectors).
The Render Cycle
- Creation Mode: Instructions create DOM nodes and store them in
LView.
- Update Mode: Instructions check current values against previous values stored in
LView. If changed, they update the DOM.
3. Dependency Injection (DI)
DI in Angular is hierarchical and split into two systems that interact:
Module Injector (R3Injector)
- Configured via
@NgModule.providers or providedIn: 'root'.
- Stored in a hierarchy of
R3Injector instances.
- Location:
packages/core/src/di/r3_injector.ts
Node Injector
- Configured via
@Component.providers or @Directive.providers.
- Not a class, but a data structure embedded in the
LView ("Expando" section).
- Uses Bloom Filters (
TView.data) to quickly check if a token is present at a specific node index before traversing up the tree.
- Resolves tokens starting from the current node, walking up the view tree (Element Injector hierarchy), and falling back to the Module Injector if not found.
4. Change Detection
- Dirty Checking: Angular checks if values bound in templates have changed.
- Strategies:
Default: Checks everything.
OnPush: Checks only if inputs change, events fire, or signals update.
- Signals: The new reactivity primitive. Signals notify the scheduler when they change, potentially allowing for fine-grained updates (Zoneless).
5. Key Directories to Know
src/render3: The Ivy rendering engine.
instructions: The runtime instructions called by compiled code.
interfaces: LView, TView, TNode definitions.
src/di: Dependency injection system.
src/change_detection: Change detection logic.
src/zone: Zone.js integration.
src/signal: Signals implementation (if present in this version, otherwise likely in primitives).
6. Conventions & Gotchas
- Prefixes: Private/Internal exports often start with
ɵ.
- Global State: Ivy relies heavily on global state (e.g.,
getLView()) during instruction execution to avoid passing context arguments everywhere. This is for performance and code size.
- Performance: The code is highly optimized for performance and memory. You will see arrays used instead of objects, bitmasks, and manual memory management patterns. Respect these patterns.
7. How to Modify Core
- Understand the Instruction: If modifying runtime behavior, find the corresponding instruction in
src/render3/instructions.
- Check
LView/TView Impact: If adding state, understand where it fits in the LView array.
- Tests: Core has extensive tests. Run them using Bazel.
1---2name: reference-core3description: Explains the mental model and architecture of the code under `packages/core`. You MUST use this skill any time you plan to work with code in `packages/core`4---5
6# Angular Core (`packages/core`) Mental Model
7
8This document outlines the architecture and mental model for `packages/core`, the heart of the Angular framework.
9
10## 1. High-Level Architecture
11
12`packages/core` contains the runtime logic for Angular. Its primary responsibilities are:
13
141. **Rendering (Ivy/Render3)**: Transforming templates into DOM updates.
152. **Dependency Injection (DI)**: Managing object creation and lifetime.
163. **Change Detection**: Synchronizing the model with the view.
174. **Reactivity**: Signals and Zone.js integration.
18
19## 2. Rendering Engine (Ivy / Render3)
20
21The rendering engine (located in `packages/core/src/render3`) uses an **instruction-based** approach.
22
23### Key Concepts
24
25- **Instructions**: The Angular compiler transforms templates into a sequence of instruction calls (e.g., `ɵɵelementStart`, `ɵɵtext`, `ɵɵproperty`). These instructions are executed at runtime to create and update the view.
26 - _Location_: `packages/core/src/render3/instructions`
27
28- **LView (Logical View)**: An array containing the _state_ of a specific view instance. It holds:
29 - DOM nodes (`RElement`, `RText`).
30 - Binding values (for change detection).
31 - Directive/Component instances.
32 - _Context_: `packages/core/src/render3/interfaces/view.ts`
33
34- **TView (Template View)**: An array containing the _static structure_ of a view. It is shared across all instances (`LView`s) of the same component/template. It holds:
35 - Property names for bindings.
36 - Node relationship information.
37 - Compiled directive definitions.
38 - _Context_: `packages/core/src/render3/interfaces/view.ts`
39
40- **Memory Layout**: `LView` and `TView` are parallel arrays. Index `i` in `LView` corresponds to metadata at index `i` in `TView`.
41 - `HEADER`: Fixed size, contains context (Parent, Host, etc.).
42 - `DECLS`: Static nodes (elements, text, pipes).
43 - `VARS`: Binding values.
44 - `EXPANDO`: Dynamic data (host bindings, injectors).
45
46### The Render Cycle
47
481. **Creation Mode**: Instructions create DOM nodes and store them in `LView`.
492. **Update Mode**: Instructions check current values against previous values stored in `LView`. If changed, they update the DOM.
50
51## 3. Dependency Injection (DI)
52
53DI in Angular is hierarchical and split into two systems that interact:
54
55### Module Injector (`R3Injector`)
56
57- Configured via `@NgModule.providers` or `providedIn: 'root'`.
58- Stored in a hierarchy of `R3Injector` instances.
59- _Location_: `packages/core/src/di/r3_injector.ts`
60
61### Node Injector
62
63- Configured via `@Component.providers` or `@Directive.providers`.
64- **Not a class**, but a data structure embedded in the `LView` ("Expando" section).
65- Uses **Bloom Filters** (`TView.data`) to quickly check if a token is present at a specific node index before traversing up the tree.
66- Resolves tokens starting from the current node, walking up the view tree (Element Injector hierarchy), and falling back to the Module Injector if not found.
67
68## 4. Change Detection
69
70- **Dirty Checking**: Angular checks if values bound in templates have changed.
71- **Strategies**:
72 - `Default`: Checks everything.
73 - `OnPush`: Checks only if inputs change, events fire, or signals update.
74- **Signals**: The new reactivity primitive. Signals notify the scheduler when they change, potentially allowing for fine-grained updates (Zoneless).
75
76## 5. Key Directories to Know
77
78- `src/render3`: The Ivy rendering engine.
79 - `instructions`: The runtime instructions called by compiled code.
80 - `interfaces`: `LView`, `TView`, `TNode` definitions.
81- `src/di`: Dependency injection system.
82- `src/change_detection`: Change detection logic.
83- `src/zone`: Zone.js integration.
84- `src/signal`: Signals implementation (if present in this version, otherwise likely in `primitives`).
85
86## 6. Conventions & Gotchas
87
88- **Prefixes**: Private/Internal exports often start with `ɵ`.
89- **Global State**: Ivy relies heavily on global state (e.g., `getLView()`) during instruction execution to avoid passing context arguments everywhere. This is for performance and code size.
90- **Performance**: The code is highly optimized for performance and memory. You will see arrays used instead of objects, bitmasks, and manual memory management patterns. **Respect these patterns.**
91
92## 7. How to Modify Core
93
941. **Understand the Instruction**: If modifying runtime behavior, find the corresponding instruction in `src/render3/instructions`.
952. **Check `LView`/`TView` Impact**: If adding state, understand where it fits in the `LView` array.
963. **Tests**: Core has extensive tests. Run them using Bazel.