What is the Observer pattern?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
The Observer pattern lets an object (the subject) keep a list of interested parties (observers) and notify all of them when its state changes. The subject does not know or care who is listening, which is the whole point: it can change without the listeners changing, and vice versa.
class Subject {
#observers = new Set();
subscribe(fn) {
this.#observers.add(fn);
return () => this.#observers.delete(fn); // hand back an unsubscribe
}
notify(data) {
for (const fn of this.#observers) fn(data);
}
}
const store = new Subject();
const stop = store.subscribe((v) => console.log("changed:", v));
store.notify(42);
stop();
Returning the unsubscribe function from subscribe is the detail that matters most in practice — without it, callers have to hold on to the exact function reference to remove it later, and forgetting is the usual cause of memory leaks.
Where you already use it
addEventListener— the DOM is one big observer system.- State libraries: Redux subscriptions, Zustand, signals in Vue and Solid.
IntersectionObserver,MutationObserver,ResizeObserver.- React's
useSyncExternalStore, which exists to subscribe to exactly this shape safely.
Trade-offs worth naming
The decoupling is real, but so is the cost: control flow becomes hard to follow because you cannot tell from the subject's code what will run when it notifies. Observers fire synchronously in subscription order, so one slow or throwing observer affects the rest — wrap calls in try/catch if listeners are untrusted. And always unsubscribe when a component unmounts.
Not the same as pub/sub
In pub/sub a broker sits between publisher and subscriber and neither knows the other exists. In the Observer pattern the subject holds the list directly.
