DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. Event-Driven Architecture in Frontend Applications
XLinkedInReddit
MediumFrontend Engineering

Event-Driven Architecture in Frontend Applications

D
DevPrep Team
February 10, 2026·1 min read·0
Table of Contents
  • Why Event-Driven?
  • Custom Event Bus
  • React Integration
  • Browser Custom Events
  • When NOT to Use Events

Event-driven architecture decouples components and enables scalable, maintainable code. At Google, we use it extensively in large SPAs.

Why Event-Driven?

Direct function calls create tight coupling. Events create loose coupling — the publisher doesn't know or care who's listening.

// Tight coupling
function addToCart(item) {
  cartService.add(item);
  analyticsService.track("add_to_cart", item);
  notificationService.show("Added to cart");
  recommendationService.update(item);
}

// Event-driven (loose coupling)
function addToCart(item) {
  cartService.add(item);
  eventBus.emit("cart:item-added", item);
}
// Each service listens independently

Custom Event Bus

class EventBus {
  #handlers = new Map();

  on(event, handler) {
    if (!this.#handlers.has(event)) this.#handlers.set(event, new Set());
    this.#handlers.get(event).add(handler);
    return () => this.off(event, handler);
  }

  off(event, handler) {
    this.#handlers.get(event)?.delete(handler);
  }

  emit(event, payload) {
    this.#handlers.get(event)?.forEach(h => {
      try { h(payload); } catch (e) { console.error(e); }
    });
  }

  once(event, handler) {
    const wrapper = (payload) => {
      handler(payload);
      this.off(event, wrapper);
    };
    return this.on(event, wrapper);
  }
}

export const eventBus = new EventBus();

React Integration

function useEventBus(event, handler) {
  useEffect(() => {
    const unsub = eventBus.on(event, handler);
    return unsub;
  }, [event, handler]);
}

// Usage
function NotificationBar() {
  const [message, setMessage] = useState("");
  useEventBus("notification:show", (msg) => setMessage(msg));
  return message ? <div className="notification">{message}</div> : null;
}

Browser Custom Events

// Dispatch
window.dispatchEvent(new CustomEvent("app:theme-changed", {
  detail: { theme: "dark" }
}));

// Listen
window.addEventListener("app:theme-changed", (e) => {
  applyTheme(e.detail.theme);
});

When NOT to Use Events

  • For parent-child communication (use props)
  • When you need a return value (events are fire-and-forget)
  • When ordering matters (events are inherently unordered)
  • For simple, direct communication between two components

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • Why Event-Driven?
  • Custom Event Bus
  • React Integration
  • Browser Custom Events
  • When NOT to Use Events

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.