ES Modules in JavaScript

Introduction

ES modules (import / export) are the standard way to split code across files in modern JavaScript. Browsers and Node.js both support them when configured correctly. This chapter covers named and default exports, re-exports, and running module files in Node.

Prerequisites

Named Export

javascript
// math.mjs
export function add(a, b) {
  return a + b;
}
 
export const PI = 3.14159;
javascript
// main.mjs
import { add, PI } from "./math.mjs";
 
console.log(add(2, 3));
console.log(PI);

Default Export

javascript
// logger.mjs
export default function log(message) {
  console.log(`[log] ${message}`);
}
javascript
// app.mjs
import log from "./logger.mjs";
 
log("server started");

One default export per module; combine with named exports when useful.

Rename on Import

javascript
// import with alias
import { add as sum } from "./math.mjs";
console.log(sum(1, 1));

Re-export Barrel File

javascript
// index.mjs
export { add, PI } from "./math.mjs";
export { default as log } from "./logger.mjs";

Node.js: Enable ES Modules

Option A — use .mjs extension (shown above).

Option B — package.json:

json
{
  "type": "module"
}

Then .js files are treated as ES modules.

Warning

With "type": "module", require() is not available in .js files—use import or separate CommonJS files (see CommonJS).

import() Dynamic Import

javascript
// Load module lazily
async function loadPlugin() {
  const mod = await import("./plugin.mjs");
  mod.run();
}
 
loadPlugin();

Returns a Promise—useful for code splitting and conditional loading.

Mini Example: Config Module

javascript
// config.mjs
export const port = Number(process.env.PORT ?? 3000);
export const host = "127.0.0.1";
javascript
// server-stub.mjs
import { port, host } from "./config.mjs";
console.log(`Would listen on ${host}:${port}`);

FAQ

.mjs vs .js?

.mjs always ES module; .js depends on nearest package.json "type".

Can I import JSON?

Node supports import data from "./file.json" with { type: "json" } in recent versions—check your Node LTS docs.

Circular imports?

Possible but tricky—refactor shared code into a third module when cycles appear.

What comes next?

CommonJS modules.