> ## Content Index
> Fetch the complete content index at: https://madewithlove.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Optimizing JavaScript packages for tree shaking
- URL: https://madewithlove.com/blog/optimizing-javascript-packages-for-tree-shaking/
- Published: 2019-04-12T11:01:56.000Z
- Updated: 2026-05-29T11:58:18.000Z
- Author: Geoffrey Dhuyvetters
- Tags: Engineering, Tutorials, JavaScript, Frontend

As an author of (open source) packages, I think you have the responsibility to protect the bundle size of your package consumer. When you publish a package that exports a whole range of modules (for example [lodash](https://lodash.com/), [ramda](https://ramdajs.com/), [date-fns](https://date-fns.org/)…) you want to make sure the package is exported in such a way that the consumer of your package (mostly bundlers) can optimize size.

One of the techniques a bundler applies is tree shaking. Tree shaking is a dead code removal technique that makes sure all unused modules are excluded from the output. It’s not hard to prepare your package for tree shaking, the decisive factor is the module format you choose.

---

Let’s have a brief intro on the 2 most popular module formats in JavaScript.

**CommonJS** was originally created in 2009 by Mozilla. Initially, it was called ServerJS but was renamed to CommonJS in the same year. This format was popularized by Node.js as it is their de facto module system. You export a module using **module.exports** & import via **require( )**.

*add.js (module)*

```javascript
const add = () => a + b;
module.exports = add;
```

*index.js (consumer)*

```javascript
const add = require('./add.js');
console.log(add(1, 2));
```

CommonJS is **dynamic** which means you can use **require( )** within loops/functions etc, this enables lazy loading patterns that can be useful in performance sensitive scenarios.

In this function **add.js** or **subtract.js** will only be loaded when the **require( )** is reached.

```javascript
const addOrSubtract = (a, b, action = 'ADD') => {
  if (action === 'ADD') {
    return require('./add.js')(a, b);
  }

  if (action === 'SUBTRACT') {
    return require('./subtract.js')(a, b);
  }

  throw new Error('Please provide a valid action (ADD or SUBTRACT).');
}
```

In 2015 a module format was added to the ECMAScript specification, which makes it the ‘official’ JavaScript module format. It’s mostly referred to as **ES2015 or ES modules**. This specification uses a combination of **import** & **export**.

*add.js (module)*

```javascript
const add = () => a + b;
export default add;
```

*index.js (consumer)*

```javascript
import add from './add.js';
console.log(add(1, 2));
```

This is just a basic example of importing and exporting, there is a lot more in [the spec](http://exploringjs.com/es6/ch%5Fmodules.html) (and open [proposals](https://github.com/tc39/proposal-export-default-from)). ES Modules are (mostly) static, you define 1 or multiple imports at the top of a file and use them in the code below. If you need a dynamic *CommonJS style* import (e.g. require) you can use **import( )**.

While some browsers support