Publish JS project as dual ES modules and CommonJS package to npm
JavaScript
186
285 commits
updated Feb 25, 2026
Publish JS project as dual ES modules and CommonJS package to npm.
src/ and dist/ dirs in repository.
You will be able to test branch by installing version from GitHub like
npm i example@you/example#fix.import { nanoid } from 'nanoid/async'.process.env.NODE_ENV for development checks, which you want
to remove in production JS bundle.You write CommonJS in your npm library sources:
// index.js
module.exports = { lib }
npx dual-publish compiles your library during publishing to npm:
// index.js
export { lib }
// index.cjs
module.exports = { lib }
// package.json
{
…
"type": "module",
"module": "index.js",
"main": "index.cjs",
"exports": {
"require": "./index.cjs",
"import": "./index.js"
}
}
Now your library can be imported natively as ESM or CommonJS:
// CommonJS
let { lib } = require('lib')
// ESM in Node.js, webpack, Parcel, and Rollup
import { lib } from 'lib'
// ESM in browser
import { lib } from 'https://cdn.jsdelivr.net/npm/lib/index.js'
lib/index.js instead of lib.js.
We need it to put package.json with module.Take a normal CommonJS project with require() and module.exports =.
Because of bug in webpack we recommend to use only named exports:
const NAME = 'a'
function change {
…
}
module.exports = { NAME, change }
Move all files into separated dirs. Rename lib.js to lib/index.js.
Old require('./lib') will work.
Add dual-publish to the project:
npm i --save-dev dual-publish
Test the result by calling npx dual-publish --check.
It will create a folder in your project with converted files.
Review them manually.
Publish your project with npx dual-publish instead of npm publish.
npx dual-publish
JavaScript
100.0%
Publish JS project as dual ES modules and CommonJS package to npm
JavaScript
186
285 commits
updated Feb 25, 2026
Publish JS project as dual ES modules and CommonJS package to npm.
src/ and dist/ dirs in repository.
You will be able to test branch by installing version from GitHub like
npm i example@you/example#fix.import { nanoid } from 'nanoid/async'.process.env.NODE_ENV for development checks, which you want
to remove in production JS bundle.You write CommonJS in your npm library sources:
// index.js
module.exports = { lib }
npx dual-publish compiles your library during publishing to npm:
// index.js
export { lib }
// index.cjs
module.exports = { lib }
// package.json
{
…
"type": "module",
"module": "index.js",
"main": "index.cjs",
"exports": {
"require": "./index.cjs",
"import": "./index.js"
}
}
Now your library can be imported natively as ESM or CommonJS:
// CommonJS
let { lib } = require('lib')
// ESM in Node.js, webpack, Parcel, and Rollup
import { lib } from 'lib'
// ESM in browser
import { lib } from 'https://cdn.jsdelivr.net/npm/lib/index.js'
lib/index.js instead of lib.js.
We need it to put package.json with module.Take a normal CommonJS project with require() and module.exports =.
Because of bug in webpack we recommend to use only named exports:
const NAME = 'a'
function change {
…
}
module.exports = { NAME, change }
Move all files into separated dirs. Rename lib.js to lib/index.js.
Old require('./lib') will work.
Add dual-publish to the project:
npm i --save-dev dual-publish
Test the result by calling npx dual-publish --check.
It will create a folder in your project with converted files.
Review them manually.
Publish your project with npx dual-publish instead of npm publish.
npx dual-publish
JavaScript
100.0%