Node.js Package Authors: Please support both CJS and ESM

endel

Endel Dreyer

Posted on June 13, 2022

Node.js Package Authors: Please support both CJS and ESM

On this post I'll describe you how you can easily add support for both CJS (CommonJS) and ESM (ECMAScript Modules) when authoring your own NPM packages.

Now that TypeScript is the go-to choice for most NPM package authors, it has never been easier to support either both CJS and ESM as "build targets".

The problem

The standard TypeScript compiler (tsc) is still a bit limited when it comes to ESM output. If you use .ts for your source-code files, it simply can't output .mjs files for you. Although there are workarounds for this limitation, it often becomes too much effort, specially if you are under a monorepo with more than one NPM package to create releases from.

The solution

Use esbuild to generate both .js and .mjs files, and tsc only for the declaration files (.d.ts).

You can use the same output directory for all of them.

npm install --save-dev esbuild
Enter fullscreen mode Exit fullscreen mode

Generating the CommonJS (CJS) output:

npx esbuild --outdir=build --platform=node --format=cjs src/*.ts
Enter fullscreen mode Exit fullscreen mode

Generating the ES Modules (ESM) output:

npx esbuild --out-extension:.js=.mjs --outdir=build --platform=node --format=esm src/*.ts
Enter fullscreen mode Exit fullscreen mode

Generating the TypeScript declaration files:

npx tsc
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can do these 3 steps through both esbuild and typescript APIs. See the full example using esbuild and typescript APIs.


Finally, for the package.json, you can combine all the 3 outputs:

  "main": "./build/index.js",
  "module": "./build/index.mjs",
  "typings": "./build/index.d.ts",
Enter fullscreen mode Exit fullscreen mode

Hope this helps!

💖 💪 🙅 🚩
endel
Endel Dreyer

Posted on June 13, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related