esbuild isn’t just a faster bundler; it’s a fundamental shift in how we think about JavaScript build tooling.

Here’s how to get it running in a typical Node.js project using npm.

First, install esbuild as a dev dependency:

npm install --save-dev esbuild

Now, create a simple JavaScript file to bundle, say src/index.js:

// src/index.js
import { greet } from './greet';

console.log(greet('World'));

And the module it imports, src/greet.js:

// src/greet.js
export function greet(name) {
  return `Hello, ${name}!`;
}

To bundle these files into a single output file, dist/bundle.js, you can run esbuild directly from your terminal. The most basic command looks like this:

npx esbuild src/index.js --bundle --outfile=dist/bundle.js

This command tells esbuild to take src/index.js as the entry point, bundle all its dependencies (--bundle), and write the output to dist/bundle.js (--outfile).

After running this, you’ll have a dist directory containing bundle.js. You can then create an index.html to include this bundled JavaScript:

<!DOCTYPE html>
<html>
<head>
    <title>esbuild Demo</title>
</head>
<body>
    <script src="dist/bundle.js"></script>
</body>
</html>

If you open this HTML in a browser and check the console, you’ll see "Hello, World!". For a Node.js environment, you could similarly run:

node dist/bundle.js

You can also integrate esbuild into your package.json scripts for easier execution. Add a "build" script:

// package.json
{
  "name": "my-esbuild-project",
  "version": "1.0.0",
  "scripts": {
    "build": "esbuild src/index.js --bundle --outfile=dist/bundle.js"
  },
  "devDependencies": {
    "esbuild": "^0.20.2"
  }
}

Now, running npm run build will perform the bundling.

Beyond basic bundling, esbuild offers powerful features. For instance, you can specify the target environment to ensure compatibility:

npx esbuild src/index.js --bundle --outfile=dist/bundle.js --target=es2017

This tells esbuild to transpile the code down to ES2017 syntax, making it compatible with older browsers.

Minification is another common requirement. esbuild does this by default in production builds, but you can explicitly enable it:

npx esbuild src/index.js --bundle --outfile=dist/bundle.js --minify

This will produce a much smaller dist/bundle.js file.

For more complex projects, you might want to split your code into multiple output files. This is achieved with the splitting and format options:

npx esbuild src/index.js --bundle --outfile=dist/bundle.js --splitting --format=esm

Here, --splitting enables code splitting, and --format=esm ensures the output is in ECMAScript Module format, which is necessary for dynamic imports and splitting to work correctly. esbuild will automatically create separate files for lazily loaded modules.

Consider a scenario where you have a large library that’s only used on certain pages. With splitting, esbuild can place that library into its own chunk. When the page loads, the main bundle executes, and if it needs the library, it can dynamically import the separate chunk, downloading it only when required. This dramatically improves initial page load times.

The core of esbuild’s performance comes from its implementation in Go. Unlike JavaScript-based bundlers, esbuild doesn’t rely on the Node.js event loop for its primary operations. Instead, it leverages Go’s concurrency primitives and efficient I/O handling to process files in parallel. This allows it to parse, transform, and bundle code at speeds that are orders of magnitude faster than traditional tools, especially on multi-core processors.

When you use --splitting and --format=esm, esbuild doesn’t just concatenate files. It analyzes import/export relationships and dynamically determines which parts of your code can be isolated into separate bundles. These "chunks" are then loaded on demand by the browser or Node.js runtime using native import mechanisms, allowing for granular control over what code is downloaded and executed at any given time.

The next step is often integrating esbuild with a framework or using its JavaScript API for more programmatic control.

Want structured learning?

Take the full Esbuild course →