Angular 21 introduced headless components, signal composition, and zoneless rendering. The old patterns don't work anymore. This is what architecture-level Angular code looks like now.
Angular Aria gives you 8 headless primitives. No styles. No opinions. Just keyboard navigation, ARIA attributes, and focus management. You provide the skin. The component handles the behavior.
Keyboard-navigable dropdown with typeahead, auto-complete, and screen reader announcements. Zero visual opinions.
Accessible toggle with full keyboard support. The headless logic is one signal. The skin is pure CSS. They never touch each other.
Reactive form() API with signal-driven validation. No FormGroup boilerplate. Computed validity propagates automatically.
No Zone.js. No monkey-patching. Change detection runs when signals change. The application bootstraps 40% faster.
Angular 21 signals are composable primitives. signal() holds state. computed() derives it. effect() reacts to it. linkedSignal() bridges external sources. resource() fetches async data reactively.
| Primitive | Role | Zoneless Behavior |
|---|---|---|
| signal() | Writable state container | Triggers change detection on .set() / .update() |
| computed() | Derived read-only value | Lazy — recalculates only when dependencies change |
| effect() | Side effects (logging, analytics, DOM) | Runs in microtask after signal graph settles |
| linkedSignal() | Writable signal synced to external source | Two-way bridge between signal and non-signal world |
| resource() | Async data that reloads when deps change | Replaces resolver + ngOnInit + subscribe patterns |
Every feature follows the same pattern: Domain defines the rules. State manages signals. Headless composes behavior. Skin renders pixels. Nothing else.
| Layer | Responsibility | Files | Depends On |
|---|---|---|---|
| 04 · Skin | CSS, template, visual presentation. No logic, no imports from state layer. | *.component.css | Headless only |
| 03 · Headless | Angular Aria directives, keyboard handlers, ARIA attributes, focus trap. | *.headless.ts | State only |
| 02 · State | Signals, computed values, effects. The reactive graph for this feature. | *.state.ts | Domain only |
| 01 · Domain | Models, interfaces, validation rules, business logic. Pure TypeScript. | *.model.ts | Nothing |
These demos implement the headless patterns above. The behavior is framework-agnostic. The skin is pure CSS. Swap the styles, keep the logic.
5 interactive tools. 6 cheat sheets. Architecture patterns. $10 one-time.