Reactivity Systems
Reactivity is the feature that made manual render calls obsolete. In a reactive framework, you change a value and the parts of the interface that depend on it update by themselves, with no event you subscribed to and no diffing you triggered. It can feel like magic the first time, but underneath it is a precise, mechanical system of tracking which computations read which values. Understanding that system demystifies modern frameworks and makes their behaviour predictable instead of mysterious.
This guide explains what reactivity is, the problem it solves that Backbone left open, and how dependency tracking, virtual DOMs, and signals each implement it.
What you'll learn
What reactivity means in a UI framework
Reactivity is a system where changing a piece of state automatically updates everything that depends on it, without explicit instructions to do so.
State as the single thing you change
In a reactive framework, the developer's job is to change state, and the framework's job is to make the interface reflect it. You never write code that says "now update this element"; you write code that changes a value, and the framework propagates that change to every computation and every piece of the interface that read it. The interface becomes a derived view of state rather than something you maintain by hand.
The problem Backbone left to the developer
Backbone had events but not reactivity, and the gap between the two is exactly the work that reactive frameworks automate.
Events without automatic propagation
A Backbone Model emits a change event, but nothing happens unless a View is explicitly listening and explicitly re-renders. The developer must connect each Model to each interested View and decide what to update. This is reactivity done manually, and in a large application the web of listeners becomes hard to keep correct. The mechanics of that manual wiring are shown in the Backbone.js guide, and removing it is the core appeal of moving to a reactive framework.
How dependency tracking works
The heart of a reactivity system is automatic dependency tracking, and the mechanism is simpler than it appears.
Reading registers, writing notifies
When a computation reads a reactive value, the system records that the computation depends on that value. Later, when the value is written, the system looks up exactly which computations depend on it and re-runs only those. No diffing of the whole interface is required because the dependency graph already knows precisely what is affected. This read-registers-write-notifies cycle, built at runtime, is what makes the update both automatic and minimal.
const count = signal(0);
effect(() => render(count())); // reading count() registers this effect
count.set(5); // writing re-runs only that effect
Virtual DOM versus fine-grained reactivity
Two broad strategies implement reactive updates, and they make different tradeoffs between simplicity and precision.
Recompute and compare, or track and target
A virtual DOM, used by React, re-runs a component to produce a fresh description of its interface, then compares it against the previous one to find what changed. Fine-grained reactivity, used by Vue and Solid, skips the comparison entirely: it knows from the dependency graph exactly which nodes to update. The virtual DOM is conceptually simpler and recomputes more; fine-grained reactivity does less work per update but tracks more state. Both eliminate the manual updates Backbone required, as compared across the framework comparisons.
Signals and the modern approach
Signals are the current expression of fine-grained reactivity, and they have spread across many frameworks because they are both fast and easy to reason about.
Reactivity as a first-class primitive
A signal is a value that knows who depends on it. Reading it inside a computation subscribes that computation; writing it notifies the subscribers. Because the dependency relationships are explicit and fine-grained, updates touch only what changed, with no component-level recomputation. Signals have been adopted well beyond their origin, appearing in frameworks that previously used other strategies, a convergence that fits the broader framework evolution toward doing less work at update time.
Why reactivity matters for maintainability
The deepest benefit of reactivity is not performance but the bugs it makes impossible to write.
Eliminating a whole class of errors
The most common bug in manual-update code is forgetting to update something after a state change, leaving the interface showing stale data. Reactivity removes that bug entirely, because the framework, not the developer, decides what to update. The result is code with fewer moving parts and less that can fall out of sync, which is why reactivity became central to nearly every framework in the modern frameworks ecosystem. It trades a little hidden machinery for a large gain in correctness.
Frequently Asked Questions
What is a reactivity system?
A reactivity system automatically updates everything that depends on a piece of state when that state changes, without explicit instructions. The developer changes a value and the framework propagates the change.
How does dependency tracking work?
When a computation reads a reactive value, the system records that it depends on that value. When the value is written, the system re-runs only the computations that depend on it, with no full-interface comparison needed.
What is the difference between a virtual DOM and signals?
A virtual DOM recomputes a component and compares the result against the previous version to find changes. Signals track dependencies precisely and update only the affected nodes, doing less work per update.
Why is reactivity better than Backbone's events?
Backbone events require the developer to manually connect Models to Views and decide what to re-render. Reactivity removes that wiring and the common bug of forgetting to update something after a state change.
Read next: the evolution of state management, or the Modern Frameworks hub.
See reactivity done by hand.
The Backbone.js guide shows the manual event wiring that reactive frameworks automate.
Explore the Backbone Guide →