# What zoneless change detection changes Angular historically used Zone.js to detect when asynchronous browser operations finished (timers, promises, DOM events, network callbacks). Zone.js made updates feel automatic: after an async event, Angular would run change detection and refresh views. Zoneless change detection removes that global interception and relies on explicit Angular notifications to schedule updates.
# Zone.js Zone.js simplified keeping UI and state synchronized, but it also caused drawbacks: change detection could run more often than necessary, debugging could be harder because of zone-related call stacks, and it could be unclear what actually triggered a UI update. Angular's move toward explicit reactive primitives aims for more predictable rendering and easier performance reasoning.
# Signals: what they are and what they do A signal is a reactive primitive representing component-local state that Angular can track directly. When code updates a signal, Angular receives a precise notification that that particular state changed. Signals provide:
- Reactive state for component-local data
- Dependency tracking for derived values
- Targeted change notifications used by templates
# Signals versus RxJS Signals and RxJS address different needs. Use signals for component-local state and derived UI values where you want fine-grained updates. Use RxJS for event streams, WebSocket data, complex asynchronous workflows, and service-level orchestration. In many apps they coexist: RxJS handles streaming and async orchestration, and signals drive local UI state that templates consume.
# How zoneless change detection works in practice Instead of Zone.js intercepting a wide set of async tasks, Angular schedules updates when it receives known notifications such as:
- Signal updates watched by templates
- Template and host event handlers
- AsyncPipe emissions
- ComponentRef.setInput() calls
- ChangeDetectorRef.markForCheck()
# Enabling zoneless mode Angular 20 introduced an API to opt into zoneless change detection. Applications can enable it using provideZonelessChangeDetection() when bootstrapping. Angular 21 makes zoneless the default. Switching requires code changes and validation of integrations.
# Migration considerations Before migrating an existing application, check the following areas:
- Third-party libraries: confirm they don't rely on Zone.js notifications.
- Reactive Forms: verify compatibility or plan incremental migration to signal-based patterns where appropriate.
- Testing: adjust tests that relied on Zone.js behavior for scheduling and async completion.
- External integrations and DOM callbacks: ensure explicit notifications are triggered where needed.
# Practical benefits and trade-offs Zoneless Angular can reduce unnecessary change-detection runs and make rendering more predictable and easier to debug. The trade-off is additional responsibility to ensure that components and integrations explicitly notify Angular when state changes. Migration work depends on how much your app and its dependencies assume global async interception.
# Bottom line