Learning on Web Dev Open is free for all.

Systems Thinking > Ship something other people installWhat a module actually is
Phase 03Ship something other people install174 of 434

What a module actually is

ESM exports live bindings, not values, and is statically analysable. Both of those facts have consequences you meet the first time you publish.

Concept15 minAI pair

An ES module exports a binding, not a value. If the module reassigns an exported variable later, every importer sees the new value, because the import is a view onto the module scope rather than a copy taken at import time. CommonJS copies at require time, which is why the same pattern gives you a stale value there. This is also why you cannot reassign an import: it is not your binding.

Imports are hoisted and statically determined, which is what makes tree-shaking possible at all: the bundler can know the whole dependency graph without running anything. It is also why import specifiers cannot be computed, and why dynamic import exists as an expression that returns a promise for the cases where the decision genuinely is at runtime.

Modules are evaluated once per specifier and cached, which makes a module scope a singleton. That is a convenient place to put a connection pool and a terrible place to put request state on a server, where one module instance is shared by every user. Circular imports resolve to a partially initialised module rather than an error, which is why the symptom is undefined rather than a helpful message.

You should now be able to

  • Explain the difference between a live binding and a copied value
  • Say why import cannot be conditional and require can
Ask the community

Loading…