Require vs Import in JavaScript
JavaScript has several module specifications, each with its own syntax. In this article, we will discuss the two most widely used module specs: CommonJS and ESM. But first, a brief history lesson!
Brief History of JavaScript Modules
In the early days of JavaScript, there was no standard way to share code. This forced developers to deal with massive JS files full of global variables. As you could imagine, these files were hard to work with; they were difficult to read, maintain, and debug.
Developers eventually started using a hack in JS called namespaces to organize their code and prevent naming conflicts. They would create a global object, and add all their code to it. Here is an example:
// namespace.js
var myNamespace = {
name: "Jane",
age: 25,
greet: function () {
console.log("Hello, " + this.name + "!");
},
};
var myOtherNamespace = {
name: "James",
age: 35,
greet: function () {
console.log("Hi, " + this.name + "!");
},
};
myNamespace.greet(); // Output: "Hello, Jane!"
myOtherNamespace.greet(); // Output: "Hi, James!"
With namespaces, you could encapsulate behavior, and prevent naming conflicts. However, namespaces also led to cluttered code, and as projects grew it became difficult to maintain a large number of namespaces.
The problem was clear - how can we organize our code and manage dependencies in a way that is easy to read, maintain, and debug?
Working Towards a Standard
Developers started working on module systems to organize their code and manage dependencies. One of the early module systems included CommonJS.
CommonJS was released in 2009, and designed specifically for loading modules synchronously in server-side development. It was later adopted by Node.js, and is still widely used in Node.js today. Everytime you use require()
to import a module, you are using the CommonJS module system.
TC39, the committee that develops the JavaScript standard, introduced a native module system that allowed developers to write modular code using the import and export statements in 2015. Named ECMAScript Modules (ESM, but also referred to as ES6 modules), they are the standard module system in JavaScript today. Everytime you use import
to import a module, you are using the ESM module system.
Today, the most commonly used module systems in JavaScript are CommonJS (const lib = require(”…”)) and ESM (import lib from ”…”).
CommonJS
CommonJS is the default module system used in Node.js. It was designed specifically for server-side development, where developers needed a way to load modules synchronously. CommonJS modules use the require()
function to import modules and the module.exports
object to export them.
Here is an example of how to export a function from a CommonJS module:
// module.js
function hello() {
console.log("Hello, world!");
}
module.exports = {
hello: hello,
};
To use this module in another file, you can use the require()
function to load it and access its exported functions or variables:
// app.js
const myModule = require("./module");
myModule.hello(); // Output: "Hello, world!"
ESM
ESM modules are used in the browser, and are the standard module system in JavaScript and TypeScript. To use ESM, you use the import
statement to import modules and the export
statement to export them.
Here is an example of how to export a function from an ES6 module:
// module.js
export function hello() {
console.log("Hello, world!");
}
To use this module in another file, you can use the import
statement to load it and access its exported functions or variables:
// app.js
import { hello } from "./module";
hello(); // Output: "Hello, world!"
Which One to Use?
I wish I could say always use ESM or CommonJS, but like in most things in life, it depends. There is no hard and fast rule.
These are some rules of thumb:
-
If you are writing code for the browser, use ESM modules.
-
If you are writing code for Node.js, use CommonJS modules for maximal compatability.
However, there are some exceptions to these rules. For example, if you are using a bundler like Webpack or Rollup, you can use ESM modules in Node.js. This is because bundlers can convert ESM modules to CommonJS modules, which is what Node.js uses.
If you check GitHub, you’ll see that these top starred projects are using some combination of CommonJS + ESM:
- FreeCodeCamp is a monorepo with some packages using CommonJS modules and others on ESM.
- Electron uses CommonJS modules and ESM.
- Node.js uses CommonJS in >5000 files & >2000 instances of ESM too!
Last Updated: