Compile Ready
Module 13 · JavaScript Design Patterns

The Module Pattern

Intermediate11m read14m practice25m total
Design PatternsClosuresIIFEEncapsulation

Introduction

The Module Pattern uses functions and closures to create a private scope, then returns only the public API that other code should call. Before native ES modules became standard, this was the classic way to avoid global variables and protect internal state.

In interviews, the module pattern is a practical test of whether you truly understand closures: private variables remain alive because exported functions keep a reference to the lexical environment where those variables were created.

Why This Matters

Interviewers ask this pattern because it connects three concepts at once: closures, encapsulation, and API design. A strong answer explains both the old IIFE style and the modern lesson behind it: expose a small surface area, keep implementation details private, and avoid accidental global state.

Theory

Core idea

A module is an object with public methods that close over private variables. The common classic form is an Immediately Invoked Function Expression (IIFE): define a function, run it once, keep its local variables hidden, and return an object.

Why an IIFE creates privacy

Function scope is not accessible from the outside. When the IIFE returns, its stack frame is gone, but any inner functions that were returned still hold a closure over the variables they use. That closure is what makes private state persistent.

Revealing module variant

The revealing module pattern defines private functions normally, then returns an object that maps public names to selected private functions. This makes the exported API easy to scan:

  • private data stays in the closure,
  • private helpers are not returned,
  • public methods are listed in one place.

Modern JavaScript context

Native ES modules now solve many original module-pattern problems: file-level scope, explicit imports, and explicit exports. However, ES module exports are not the same as per-instance private state. A closure-based module is still useful for interview exercises, small factories, counters, memoizers, and objects that need private mutable data without classes.

Common pitfalls

Do not expose the private object itself unless callers are allowed to mutate it. Returning items directly from a shopping cart module breaks privacy because external code can push into it. Return copies, derived values, or narrow methods instead.

Visual Diagrams

IIFE module shape
global code
   |
   v
call IIFE once
   |
   +-- private variables live in the closure
   +-- private helper functions stay hidden
   |
   v
returned public API object
   |
   +-- method A closes over private state
   +-- method B closes over private state

The caller receives only the returned API; the private lexical environment remains reachable through closures.

Code Examples

Classic IIFE module

The count variable cannot be read directly. Only the returned methods can interact with it.

Loading…

Revealing module variant

Private functions are declared first. The returned object reveals only the names that should be public.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1const wallet = (function () {
2 let balance = 0;
3
4 return {
5 deposit: function (amount) {
6 balance += amount;
7 console.log(balance);
8 },
9 getBalance: function () {
10 return balance;
11 }
12 };
13})();
14
15wallet.deposit(10);
16wallet.balance = 100;
17console.log(wallet.getBalance());
18console.log(wallet.balance);

Coding Exercises

Implement a private counter module

Medium

Implement createCounterModule(initialValue) using the module pattern. It should return an object with increment(), decrement(), reset(), and getValue(). The current value must remain private; callers should not be able to mutate it except through the public methods.

Interview Questions

1How does the module pattern create private state in JavaScript?

It creates a function scope, usually with an IIFE or factory function, stores state in local variables, and returns public methods that close over those variables. Outside code cannot access the local variables directly, but the public methods keep them alive through closure references.

Asked at:MicrosoftAmazonMeta

Follow-ups

  • How is this different from an ES module?
  • What is the revealing module pattern?
2What are the trade-offs of the module pattern compared with classes?

The module pattern gives strong privacy through closures and a simple public API. It is excellent for single modules or factory-created objects with private state. Compared with classes, each instance can allocate new function objects unless methods are shared carefully, and inheritance or prototype-based optimisations are less direct. Modern code often uses ES modules or classes with private fields, but closure privacy remains interview-relevant and useful.

Quiz

1. What keeps private variables alive after an IIFE module has returned?

2. Which statement best describes the revealing module pattern?

Summary

  • The module pattern uses closures to protect private state and expose a small public API.
  • An IIFE runs once and returns methods that continue to reference its private lexical scope.
  • The revealing module variant lists public methods clearly while keeping helpers private.
  • Modern ES modules reduce the need for IIFEs, but closure-based privacy remains a core interview skill.

Cheat Sheet

Shape: IIFE or factory function + private variables + returned API.

Privacy mechanism: closure over local variables.

Revealing module: define private functions, return selected public names.

Use for: encapsulated counters, carts, memoizers, single-purpose services.

Avoid: returning mutable private objects directly.