Two Ways to Connect Code: Understanding CommonJS and ES Modules in JavaScript
CommonJS loads modules dynamically at runtime using require, while ES Modules use static import/export syntax that is analyzed before execution, enabling better structure and optimization.
There was a time when JavaScript didnât really know how to organize itself.
You wrote one file.
Then another.
And somehow, they were all expected to work together.
No boundaries.
No clear structure.
Just a shared global space where everything lived.
It workedâuntil it didnât.
Because as soon as code started growing, something became obvious:
Not everything should know about everything else.
The Need for Separation
When code is split across files, a new question appears:
How does one file know about another?
Not just that it existsâ
but what it exposes, and when it becomes available.
This is where modules enter.
Not as a feature of convenienceâŚ
but as a way to bring order to growing complexity.
Two Different Answers
JavaScript ended up with two major ways of solving this:
CommonJS
and
ES Modules
At first glance, they seem similar.
Both allow you to export something from one file and import it into another.
But underneath, they reflect two very different ways of thinking.
CommonJS: Loading on Demand
CommonJS was designed in a world where JavaScript ran on servers.
Where flexibility mattered more than structure.
So it approached modules like this:
âWhen you reach this line⌠load the file.â
const add = require("./math")require is just a function.
It runs when the code runs.
Which means:
- you can call it conditionally
- you can compute paths dynamically
- you can decide at runtime what to load
This makes it flexible.
But also a bit unpredictable.
Because the structure of your program isnât fully known until it executes.
ES Modules: Understanding Before Running
ES Modules take a different approach.
They donât wait.
They analyze everything first.
import { add } from "./math.js"This isnât a function call.
Itâs part of the language itself.
Before your code runs, JavaScript already knows:
- what files are connected
- what is being imported
- how everything fits together
It builds the map first.
Then executes.
The Difference Beneath the Syntax
At the surface, it looks like:
require vs import
But thatâs not the real difference.
The real difference is timing.
CommonJS asks:
âWhat should I load right now?â
ES Modules ask:
âWhat does the entire structure look like before anything runs?â
One reacts.
The other prepares.
Flexibility vs Predictability
Because of this, each system leans in a different direction.
CommonJS gives you freedom.
You can write:
if (condition) {
const lib = require("./lib")
}And it works.
But that freedom comes with uncertainty.
Tools canât easily predict what your program will do.
ES Modules remove that flexibility.
You canât import conditionally in the same way.
But in exchange, everything becomes visible upfront.
And that visibility changes whatâs possible.
When Code Becomes a System
When JavaScript was small, flexibility was enough.
But as applications grew, something else became important:
Understanding the system as a whole.
Because once you can see the full structure:
- you can remove unused code
- you can optimize loading
- you can reason about dependencies
This is why ES Modules became the standard.
Not because theyâre simplerâ
but because they make large systems manageable.
A Subtle Shift in Thinking
CommonJS feels like asking for values:
âGive me whatâs inside that fileâ
ES Modules feel like creating connections:
âLink me to that piece of the systemâ
Itâs less about retrievingâŚ
and more about relating.
Where You See It Today
If youâre working with modern toolsâVue, Nuxt, Viteâ
youâre already living in the ES Module world.
Even if it doesnât always feel explicit.
CommonJS still exists, especially in older Node.js code.
But the direction is clear.
JavaScript is moving toward structure over flexibility.
A Final Thought
Both systems solve the same problem.
They let code exist in separate places, while still working together.
But they answer a deeper question differently.
CommonJS says:
âIâll figure it out as I goâ
ES Modules say:
âI want to understand everything before I beginâ
And somewhere between those two ideasâŚ
is the story of how JavaScript grew up.