← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Reactive Patterns — Observer & Pub/Sub in JavaScript

JavaScript ES2015 Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). ESLint can flag global window variables and direct DOM querying patterns (per detection_hints), but detecting missing event listener cleanup or inefficient event-based patterns requires static analysis beyond linting or runtime profiling — not caught automatically by default tooling.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is straightforward: replace global state/direct DOM queries with CustomEvent + dispatchEvent. This typically affects one or two components' communication layer, not cross-cutting refactor. Memory leak fixes (removing listeners) are localized changes per component.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Reactive patterns apply across web contexts and affect how all future component communication is architected. Choice of event-based vs. global state shapes how developers think about component decoupling; it influences testing, state management, and coordination logic across many feature teams — not just one component, but a persistent pattern.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field directly names it: developers assume reactive programming *requires* React/Vue/RxJS, so they either over-engineer with RxJS or fall back to global variables. CustomEvent's subtle API (event.detail for payload, listener cleanup gotchas, memory leak risk on SPA-like page mutations) contradicts how similar patterns work in framework-land, creating cognitive friction for developers familiar with framework reactivity.

About DEBT scoring →

Also Known As

EventEmitter CustomEvent pub/sub JS event bus reactive programming

TL;DR

EventEmitter, CustomEvent, and pub/sub patterns coordinate state changes across components without tight coupling — common in PHP-rendered pages with JS islands.

Explanation

Patterns: EventEmitter (Node.js), CustomEvent + dispatchEvent (browser), and simple pub/sub objects. CustomEvent lets PHP-rendered DOM elements communicate: a checkout component fires 'cart:updated', a header badge listens. No framework needed. EventTarget interface can be extended. This pattern works well in 'islands architecture' where PHP renders HTML and small JS components communicate via events rather than shared state.

Common Misconception

Reactive programming requires React, Vue, or RxJS — the browser's native CustomEvent and addEventListener are sufficient for coordinating PHP-rendered components without a framework.

Why It Matters

PHP renders multiple independent HTML components; JavaScript needs a lightweight way to keep them in sync without a full SPA framework — custom events provide decoupled communication.

Common Mistakes

  • Not removing event listeners on element removal — memory leak
  • Using global variables to share state instead of events
  • Over-engineering with RxJS when CustomEvent suffices

Code Examples

✗ Vulnerable
// Global variable coupling — fragile:
window.cartCount = 3;
document.querySelector('#badge').textContent = window.cartCount;
✓ Fixed
// Custom event — decoupled:
// Cart component dispatches:
document.dispatchEvent(new CustomEvent('cart:updated', {
    detail: { count: 3, total: 29.99 }
}));

// Badge component listens:
document.addEventListener('cart:updated', (e) => {
    badge.textContent = e.detail.count;
});

// Simple pub/sub for Node/vanilla:
const bus = {
    on: (e, fn) => document.addEventListener(e, fn),
    off: (e, fn) => document.removeEventListener(e, fn),
    emit: (e, d) => document.dispatchEvent(new CustomEvent(e, { detail: d })),
};

Added 17 Mar 2026
Edited 22 Mar 2026
Views 111
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 2 pings S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 2 pings M 0 pings T 1 ping W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M
Amazonbot 1
No pings yesterday
PetalBot 12 Amazonbot 10 Ahrefs 8 Google 7 Bing 6 ChatGPT 5 SEMrush 5 Perplexity 4 Scrapy 4 Applebot 3 Majestic 2 Unknown AI 2 Twitter/X 2 Meta AI 1 Brave Search 1
crawler 68 crawler_json 4
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
JavaScript javascript The programming language of the browser — it reads and modifies the page (the DOM), reacts to user events, and fetches data without reloading.

JavaScript is the only language browsers execute, so every interactive behaviour on the web goes through it. Its two defining traits — single-threaded event loop and loose typing (== coercion) — explain the majority of both its bugs and its design patterns.

💡 Default to const, use === always, and reach for let only when a value genuinely reassigns.

Ask Codex about JavaScript →
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use CustomEvent + dispatchEvent for cross-component communication in PHP-rendered pages — no framework required
📦 Applies To
javascript ES2015 web
🔗 Prerequisites
🔍 Detection Hints
Global window variables for component communication; direct DOM querying across unrelated components; no event-based decoupling
Auto-detectable: ✗ No eslint
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: High Context: File Tests: Update


✓ schema.org compliant