ES Modules in Node.js: import, export and require(esm)
Node.js supports two module systems: the original CommonJS (require) and standard ES modules (import). New projects should use ESM, but you'll meet both.
Turning on ESM
// package.json
{ "type": "module" }
With "type": "module", .js files are ESM. Without it, they're CommonJS. .mjs is always ESM and .cjs is always CommonJS.
Syntax
// math.js
export function add(a, b) { return a + b; }
export default function multiply(a, b) { return a * b; }
// app.js
import multiply, { add } from './math.js'; // the extension is required
import fs from 'node:fs/promises'; // node: prefix for built-ins
No __dirname? Use import.meta
console.log(import.meta.dirname); // directory of this file
console.log(import.meta.filename); // full path of this file
const configPath = new URL('./config.json', import.meta.url);
Top-level await
const config = JSON.parse(await fs.readFile(configPath, 'utf8'));
await db.connect();
JSON imports
import pkg from './package.json' with { type: 'json' };
Mixing with CommonJS
- ESM can
importCommonJS packages;module.exportsbecomes the default export. - Current Node.js versions also let CommonJS
require()an ES module, as long as it doesn't use top-level await. This removed the biggest pain of the migration. - In older versions, use dynamic
await import()from CommonJS.
Common errors
- Cannot use import statement outside a module - add
"type": "module"or rename to.mjs. - ERR_MODULE_NOT_FOUND for a local file - add the
.jsextension to the import path. - require is not defined - you're in ESM; use
importorcreateRequire.
Was this article helpful?
Comments
No comments yet. Have a question or a tip? Be the first to share it.