← Lessons

quiz vs the machine

Gold1470

Frontend

The Module System ESM vs CJS

ES modules and CommonJS load and bind exports in fundamentally different ways.

5 min read · core · beat Gold to climb

Two ways to share code

JavaScript has two major module systems. CommonJS grew up in Node with require and module exports, while ES modules are the standard with import and export. They differ in timing and binding.

  • CommonJS loads modules synchronously at require time.
  • ES modules are parsed first, then linked, then evaluated.
  • Both let files share and reuse code.

Static structure and live bindings

ES module imports and exports are static, fixed at parse time before any code runs. This lets tools analyze the graph and enables tree shaking. CommonJS exports are a plain object resolved at runtime.

  • ESM imports are live bindings, so they reflect later changes to the export.
  • CommonJS gives a copy of the value at the moment of require.
  • ESM is asynchronous and supports top level await.

Mixing the two is awkward, since a CommonJS module sees an ES module only through dynamic import. The static nature of ESM is what makes modern bundlers smart, but it also forbids conditional top level imports.

Key idea

ES modules use static, live bindings resolved before execution, while CommonJS uses dynamic require that copies the export value at call time.

Check yourself

Answer to earn rating on the learn ladder.

1. When are ES module imports resolved?

2. What does a CommonJS import give you?

3. Which feature does the static structure of ESM enable?