Skip to content
67 changes: 67 additions & 0 deletions docs/architecture/adr/0028-angular-signals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
adr: "0028"
status: "Accepted"
date: 2025-11-24
tags: [clients, angular]
---

# 0028 - Adopt Angular Signals for Component State

<AdrTable frontMatter={frontMatter}></AdrTable>

## Context and Problem Statement

Angular has adopted a new reactive primitive, signals. Signals have various improvements over RxJS:
performance, simplicity, and deeper integrations into the rest of the framework.

RxJS will become an optional dependency of Angular. Certain asynchronous workflows will still
benefit from RxJS--signals are synchronous. Furthermore, being a part of the core Angular library,
Angular signals cannot readily be used in non-Angular environments.

As such, Signals should be the default when operating _in the view layer_: components, directives,
pipes, and services that are tightly coupled to the UI/Angular. Services that primarily deal with
business logic should prefer RxJS to maximize portability (or, even better, be moved to the Rust
SDK).

## Decision

Signal-based APIs (inputs, outputs, child queries) will be required in components and directives via
linting:

- `@Input()` โ†’ `input()`
- `@Output()` โ†’ `output()`
- `@ViewChild`/`@ContentChild` โ†’ `viewChild()`/`contentChild()`

Services tightly coupled to Angular should use signals. Services with business logic should prefer
RxJS for portability. Use `toSignal()` and `toObservable()` to bridge between the two when needed.

Existing code will be migrated gradually. New code must use signal-based APIs.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿ’ญ Consider adding guidance on the migration strategy. Should this happen incrementally per feature area? Are there any teams or components that should be prioritized? ADR 0027 had a detailed "Implementation Plan" section which was helpful.

Copy link
Contributor

@theMickster theMickster Nov 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐ŸŽจ I agree that this ADR needs an Implementation Plan section. I do not think that it needs to be overwhelming and could even point to some of the specific sections in the Angular Migrations Wiki

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggested approach would be for all teams to run the signal related migrations for all code they own, ideally feature by feature. But if we define a plan we also need to put weight behind it, we have plenty of existing ADRs with implementation plans that are pending.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, yes, the primary intent of a plan in an ADR is the steps by which each team will go through to accomplish the goal. We cannot set the timing of when the plan is done, but it does help to influence the timing when we can approach stakeholders showing a prescriptive plan on how to do the work.


## Consequences

**Positive:**

- Improved performance and simpler change detection
- Clear path to removing Zone.js dependency
- Better debugging experience
- Aligned with Angular's direction
- Simpler than RxJS for many common use cases

**Negative:**

- Temporary complexity during migration with mixed RxJS/Signals patterns
- Learning curve for team members unfamiliar with signals
- Migration effort required for existing codebase

## Reasons against other options

- Disallow usage of signals and only use RxJS for reactivity.
- This is a non-starter. Signals are being built into Angular.
- Continue the status quo of adhoc usage.
- Having multiple ways to do the same thing leads to analysis paralysis and complicated code.
- Signals + OnPush change detection provide a clear path to removing Zone.js. With that comes
notable performance and debugging improvements.

## Further reading

- [Angular docs](https://angular.dev/guide/signals)
Loading