ESM vs CommonJS in package.json
The type field in package.json determines how Node.js treats .js files. Use the generator above to switch between module (ESM) and commonjs (CJS) and see how the output changes.
Basic Info
Module Config
{
"name": "my-nextjs-app",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "index.js",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"next": "^15.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"typescript": "^5.7.0",
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"eslint": "^9.0.0",
"eslint-config-next": "^15.0.0"
},
"license": "MIT"
}4
Scripts
3
Deps
6
DevDeps
Press Ctrl+Enter to copy
What type: module does
Setting "type": "module" tells Node.js to treat .js files as ES modules. This enables import/export syntax, top-level await, and import.meta. Without it, Node.js treats .js as CommonJS (require/module.exports). You can override per-file with .mjs (always ESM) and .cjs (always CJS).
Key differences in practice
ESM: import/export, top-level await, import.meta.url instead of __filename, no require(). CJS: require/module.exports, __filename/__dirname, synchronous loading, JSON import via require(). ESM is strict by default, CJS is sloppy mode. ESM imports are live bindings, CJS exports are value copies.
Migrating from CJS to ESM
Steps: 1) Set "type": "module" in package.json. 2) Rename .js to .mjs for gradual migration, or convert all at once. 3) Replace require() with import. 4) Replace module.exports with export. 5) Replace __dirname with path.dirname(fileURLToPath(import.meta.url)). 6) Add file extensions to relative imports.
Publishing dual-format packages
Dual packages support both CJS and ESM consumers. Use the exports field with conditional exports: 'import' points to ESM, 'require' points to CJS. Build tools like tsup, unbuild, or pkgroll generate both formats from the same TypeScript source. Test both entry points before publishing.
Frequently Asked Questions
Should new projects use ESM or CommonJS?
New projects should use ESM ("type": "module"). ESM is the JavaScript standard, supported by all modern browsers and Node.js 14+. CJS is legacy. The ecosystem is rapidly moving to ESM-only — major packages like chalk, got, and execa are ESM-only.
Can I use require() in an ESM project?
Not directly in .js files when type is module. You can use createRequire from the 'module' built-in, or use dynamic import() which works in both ESM and CJS. For JSON files, use import with the assert syntax or createRequire.
What if my dependency is CJS-only?
ESM can import CJS modules using default import syntax: 'import pkg from "cjs-package"'. Named exports may not work — use default import and destructure. This is a Node.js interop feature that makes migration smoother.
Related Generate Tools
MCP Config Builder
Build MCP configuration files visually for Claude Desktop, Cursor, VS Code, Windsurf, and Claude Code with 16 server templates
JWT Builder
Build and sign JSON Web Tokens with HMAC, RSA, and ECDSA algorithms — visual payload editor with expiration presets
tsconfig.json Builder
Build TypeScript tsconfig.json visually with framework presets, explanations for every option, and one-click download
Security Headers Generator
Generate HTTP security headers for Nginx, Apache, Vercel, Netlify, and Cloudflare with presets, security scoring, and multi-format output