DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk5 min

JavaScript Design Patterns: Choose the Right Fit as Your App Grows

Choose JavaScript design patterns by the problem they solve: code boundaries, object creation, event notification, or shared state. See practical examples and tradeoffs.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

JavaScript design patterns help when they address a real source of change: complicated object creation, code that needs a clear boundary, or updates that must reach multiple consumers. They are reusable approaches, not a checklist or a guarantee of scalability. Start with the problem and the simplest mechanism that solves it.

What JavaScript design patterns solve

A design pattern is a reusable way to approach a recurring design problem. In a growing application, the useful question is not “Which patterns should I use?” but “What is changing, and how can I limit the cost of that change?” A pattern may reduce coupling or isolate changes, but it also adds concepts and indirection. Use it when that tradeoff fits the application.

As an Amazon Associate I earn from qualifying purchases.

JavaScript’s standardized core is ECMAScript. Browser APIs and other host capabilities surround the language; they are not themselves part of the ECMAScript specification. MDN’s overview of JavaScript technologies explains the distinction.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to choose a pattern

Evaluate an approach against the pressure you actually have, rather than its name or popularity:

  • Coupling: How much must a consumer know about the implementation?
  • Change isolation: If behavior changes, how many callers need edits?
  • Complexity: Does the pattern remove complexity or merely move it behind another layer?
  • Testing and instance isolation: Can tests create independent instances without shared state leaking between them?
  • Lifecycle: Does the approach create subscriptions, resources, or other work that needs explicit cleanup?
  • Existing mechanisms: Does JavaScript or your framework already provide the capability?

Module pattern: organize code behind a boundary

Use modules to group related behavior and control what other parts of an application can access. Modern JavaScript has native modules with import and export; they are the normal starting point for organizing application code. MDN’s JavaScript modules guide covers exports, imports, and dynamic loading.

// cart.js
export function total(items) {
  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}

// checkout.js
import { total } from "./cart.js";

export function checkout(items) {
  return { amount: total(items) };
}

The module boundary lets callers depend on the exported API instead of the module’s internal details. Its cost is that boundaries and dependency direction still need thought; a file split alone does not make responsibilities coherent.

How this differs from the historical closure-based Module pattern

Older JavaScript examples often use a function closure to hide state and return a public object. That technique remains useful when a closure is specifically needed, but it should not be presented as the default alternative to native modules in modern application code. The underlying idea—encapsulate implementation behind a public interface—can be expressed with ECMAScript modules. MDN’s JavaScript Guide also covers closures and modules.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Factory pattern: separate requests from construction

Consider a factory when callers should ask for a product without owning every construction detail, or when the product varies by input or environment. Patterns.dev describes Factory as an object-creation pattern.

function createNotifier(channel) {
  if (channel === "email") {
    return { send: message => sendEmail(message) };
  }
  if (channel === "console") {
    return { send: message => console.log(message) };
  }
  throw new Error(`Unsupported channel: ${channel}`);
}

const notifier = createNotifier("console");
notifier.send("Build complete");

The caller depends on the returned capability, not the details of choosing and assembling an implementation. This can make a change to construction local. The tradeoff is another layer to understand; if there is only one simple object and no variation to hide, direct construction is clearer.

Observer pattern: notify multiple interested consumers

Use an observer-style subscription when one event or state change needs to notify multiple consumers that should not be tightly coupled to the producer. Patterns.dev describes observables as notifying subscribers when an event occurs.

function createEmitter() {
  const listeners = new Set();

  return {
    subscribe(listener) {
      listeners.add(listener);
      return () => listeners.delete(listener);
    },
    publish(value) {
      for (const listener of [...listeners]) {
        try {
          listener(value);
        } catch (error) {
          queueMicrotask(() => { throw error; });
        }
      }
    }
  };
}

const changes = createEmitter();
const unsubscribe = changes.subscribe(value => render(value));
changes.publish({ status: "saved" });
unsubscribe();

This example makes lifecycle and behavior explicit: subscribing returns a cleanup function; publishing iterates over a snapshot so changes to subscriptions during notification do not alter the current iteration; and one listener’s synchronous error does not prevent later listeners from running. Rethrowing asynchronously surfaces the error, but applications may instead choose a central error handler. Observer systems require deliberate choices about cleanup, error handling, and ordering; for a single consumer, a direct function call is often simpler.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Singleton: share an instance only when sharing is intentional

A singleton provides shared access to one instance. It can suit a resource that genuinely must be shared, but global shared state makes dependencies less visible and can make tests or isolated application instances harder to reason about. Patterns.dev includes Singleton among its JavaScript pattern topics.

// Prefer explicit ownership when possible.
function createApplication({ storage }) {
  return {
    save(key, value) {
      storage.setItem(key, value);
    }
  };
}

const app = createApplication({ storage: window.localStorage });

Passing the dependency makes ownership and test substitution explicit. A singleton may still be justified for a truly process-wide or application-wide resource; avoid making unrelated state global merely to ensure there is one instance.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Proxy, Mediator, and middleware: add interception or coordination for a reason

Patterns.dev’s catalog also includes Proxy, Mediator, and other patterns. They are options for concrete pressures, not steps every application should take.

  • Proxy: Consider it when access to an object needs controlled interception, such as validation or lazy behavior. Interception can make behavior less visible at the call site.
  • Mediator: Consider it when components are becoming tangled through direct coordination and a central interaction point would reduce those dependencies. The mediator itself can become a new concentration of complexity.
  • Middleware: Consider it when request or message processing needs composable stages. The order of stages and how errors or short-circuits behave must be clear.

If the application has no meaningful interception, coordination, or processing pipeline problem, these abstractions are unnecessary.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Where to learn more

Patterns.dev is a free resource covering design, rendering, and performance patterns for vanilla JavaScript and modern frameworks. Its catalog includes Module, Factory, Observer, Singleton, Proxy, and related topics.

Addy Osmani’s Learning JavaScript Design Patterns is a book-length resource focused on this subject. Check which edition you are using and compare language-specific examples with current documentation, especially for modern modules. MDN’s JavaScript Guide is a current reference for language features including modules, classes, promises, and closures.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.