How to set up ES module library for the frontend JavaScript

This article will show how to set up an npm library package as an ES module that can be easily used in other packages, with a minimum size impact.

Library code

I generated the package.json with npm run -y. The only difference was adding "type": "module". library/package.json:

  "name": "library",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "keywords": [],
  "author": "",
  "license": "ISC"

The library itself is very simple, library/index.js:

const valueA = "function A",
  valueB = "function B";

export function functionA() {
  return valueA;

export function functionB() {
  return valueB;

By moving values to const, I was hoping to trick bundler leave some redundant code, but they managed pretty well.

Application code

As simple the library is the test application webpack/src/index.js & esbuild/src/index.js:

import { functionA } from "../../library";

console.log("Hello!", functionA());

Alternatively, I could import the library as a whole:

import * as library from "../../library";

console.log("Hello!", library.functionA());

But in my simplified example, both bundlers manage just fine to leave unnecessary code behind.

Webpack config

I generated my code with my webpack-starter. The only change to webpack configuration was switching to production mode - otherwise, the build was full of comments. The resulting build command:

    "build": "webpack --mode=production"

Esbuild config

I used similar generate as above (esbuild-starter), and switched to minified output - so both bundlers are used in similar circumstances. The build command:

    "build": "esbuild --bundle src/index.js --outfile=dist/main.js --minify"

Build output

Both bundlers build the application code as they should - importing the one method we used and ignoring the other one. Interestingly, we didn't need to set "sideEffects": false to make it happen - just using ES modules seems to be enough.

Webpack output

(()=>{"use strict";console.log("Hello!","function A")})();

Webpack (or Babel) is pretty smart about minification - it reduces all my code into a static value that is always the output.


(()=>{var o="function A";function n(){return o}console.log("Hello!",n());})();

esbuild is less efficient with simplification, but it correctly removes the other exported function.


I cover basics of bundler in those video courses:


In this article, we have seen one of the approaches you can take to build a JS library as an ES module.