Skip to content

/config/nodejs/package-json-type-module

package.json "type": "module": ES modules in Node.js

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · v24.20.0updated 2026-10-20
tool
Node.js
file
package.json
key
type
type
"module" | "commonjs"
default
"commonjs"

The "type" field in package.json decides how Node.js loads .js files in that package: "module" makes them ES modules, "commonjs" (the default when the field is missing) makes them CommonJS. .mjs files are always ES modules and .cjs files are always CommonJS, whatever type says.

Example

bash
npm init -y >/dev/null
npm pkg set type=module
echo 'export const greet = (n) => `hello, ${n}`;' > lib.js
echo 'import { greet } from "./lib.js"; console.log(greet("esm")); console.log(typeof require);' > main.js
node main.js

Output

hello, esm
undefined

require is not defined in ES modules. Use import, or createRequire from node:module when you need to load a CommonJS-only file.

What changes with "type": "module"

"type": "commonjs" (default)"type": "module"
.js filesCommonJSES modules
import / exportonly in .mjsyes
require(), module.exportsyesonly in .cjs
__dirname, __filenameyesuse import.meta.dirname / import.meta.filename
Relative importsextension optionalextension required: ./lib.js
Top-level awaitnoyes

Pitfalls

  • Relative ESM imports need the file extension: import "./lib" fails with ERR_MODULE_NOT_FOUND.
  • Config files of some tools (for example older .eslintrc.js) are loaded with require; rename them to .cjs after switching.
  • The field applies to the folder of that package.json and its subfolders, up to the next package.json.

Sources