Repository navigation
Use ESModules instead of module.exports #786
Description
Activity
It's not supported natively, so a build step would be required. Unfortunately, package management for the different types of modules still is pretty terrible. This is why most large modules are still CJS exported.
Reacted by BenReacted by Victoria RodriguezYou are right...
Conditional exports be a solution when not experimental anymore, or for next major:
// package.json
{
"main": "./main-require.cjs",
"exports": {
"import": "./main-module.js",
"require": "./main-require.cjs"
},
"type": "module"
}https://nodejs.org/dist/latest-v15.x/docs/api/packages.html#packages_conditional_exports
Storing it here to not loosing this...
Reacted by Josh Junon, Evgeny, Jo Torsmyr, Jake Chvatal and Alexander KachkaevAny news on this topic?
In Node.js ESM this works for me:
import debugModule from 'debug';
const debug = new debugModule('foo');Reacted by Adam Mikacich, basaran, milahu, Jonathon Hill, François Jacques and RedX2501Reacted by Francisco SantorelliYep, v5 will be pure ESM.
Reacted by Jo Torsmyr, Jimmy Wärting, Ahacad, A-J Roos, Jaid, Robert Thompson, milahu, Bjørn Stabell, YugoCode, fratzinger and 9 moreReacted by nickk and Victoria RodriguezReacted by RomanReacted by Ray Foss and RomanIt would be cool to see debug being a ESM only package, It would put pressure on many packages towards upgrading their commonjs packages to ESM as well and benefit the hole js ecosystem in the end.
otherwise they can still use a older version of debugReacted by Jimmy Wärting, r/SUNS, Burhan Ali, Jon Koops and RomanReacted by Kevin Van Lierde and Victoria RodriguezReacted by Jaid and RomanHi @Qix-, we've been working on ESM support for
ms, and it would be great to get your feedback if you have some time:
vercel/ms#163This work is also published as
3.0.0-beta.2.The workaround suggested in the comment above
In Node.js ESM this works for me:
import debugModule from 'debug';
const debug = new debugModule('foo');didn't work for me with the version 4.3.3.
I get the error
TypeError: debugModule is not a constructor.Generally if I have
"type": "module"in my package.json an import results in an empty object{}. Importing it in a cjs module results in a function.Any other workaround for usage in an es module? Or do I better wait for the next major release?
import makeDebug from 'debug'; const debug = makeDebug('foo:bar'); debug.enabled = true; debug('hi');Works fine for me.
Reacted by Konstantin, Mohamed ELIDRISSI, S.Y. Lee, Timothy Huynh, Nick Sweet, Jeffrey Yasskin, Bartek Kus and ModeneroReacted by Jose Javier Sanahujawe should at least discourage this antipattern
var debug = require('debug')('http')it's bad to call/chain require, it only makes it harder for those who wish to swtich to esm at some point later
should rather beconst debugFactory = require('debug') const debug = debugFactory('foo:bar')
Reacted by Jeremy Combs, Jimmy Wärting, Ray Foss, Kevin Van Lierde, Eamon, Dmitry, Modenero, Mitra Ardron and Peter@jimmywarting agreed, PR welcome. That's a good start.
Debug is not a class. Don't call it with
new.Debug is not a class. Don't call it with
new.Thank you, @qix. I deleted my comment since it was incorrect.
I've been doing similar research into CJS/ESM for metalsmith and documented findings in this issue. TLDR:
Tests using a linked metalsmith package on diffferent Node versions with NVM resulted in inconvenient results for either the user (both ESM/CJS) or the maintainer:
- specifying a package.json exports property will almost certainly result in a semver-major breaking change
- specifying a shallow index.mjs wrapper and declaring"type": "commonjs" was inconvenient for ESM users as you needed to import from '/index.mjs'
- declaring "type": "module" would require including a bundler with dual ESM/CJS builds
- unit testing (with mocha) was a pain
In the case of debug, potentially even more build outputs would be required to work with native browser imports & bundlers.
The only "safe" option to support both CJS/ESM with no rewrite required in Node was using a singlemodule.exports = defaultexport as debug does in v4Reacted by Victoria Rodriguez and Robert SorianoNot using ESModules is breaking my build. This lib is buried deep in dependency chain of a lib I wanted to use and it is now not usable beucause of the incorrect modules.export usage. So, please fix soon, as this might break down many builds.
import makeDebug from 'debug'; const debug = makeDebug('foo:bar'); debug.enabled = true; debug('hi');Works fine for me.
hey @Qix-
How do you get this to work? I get the following error:x does not provide an export named 'default'Reacted by Yves GalanteLooks like starting April when Node.js 18 becomes end-of-life it will be possible to move to ECMAScript modules in a backwards compatible manner for all version of Node.js receiving active support. When this time comes I can dedicate effort to help resolve pending issues and assist in the migration.
Reacted by Jo Torsmyr, Bruno Heridet, Jean Honlet, v1rtl, Alexander Lichter, Filip Wachowiak, Wind and Romanrequire(esm)landed and was backported to Node 20 too! With Node 18 EOL, all existing non-EOL Node versions support it now 👏🏻Reacted by Wind, Josh Junon, Marvin Hagemeister, Kevin Deng and Romanproductdevbook commented
on Jun 19, 2025 on Jun 19, 2025 · Hidden as off-topicshow commentMore actions
Today, debug use module.exports facility.
But nodejs and browser can support import / export notation, aka es6 modules.
While preparing the v5, why not going into that mode?
#656 ?