Skip to main content
Bun’s bundler API is heavily inspired by esbuild. Migrating from esbuild to Bun’s bundler should be relatively straightforward. This document briefly explains why you might consider migrating to Bun’s bundler and provides a side-by-side API reference for those already familiar with esbuild. There are a few behavioral differences to be aware of.
Bundling by default. Unlike esbuild, Bun always bundles by default. That’s why the --bundle flag doesn’t appear in Bun examples. To transpile each file individually, use Bun.Transpiler.
It’s just a bundler. Unlike esbuild, Bun’s bundler does not include a built-in dev server or file watcher. It’s just a bundler. The bundler is designed to be used with Bun.serve and other runtime APIs to achieve the same effect. As such, all HTTP/file-watching related options are not applicable.

Performance

With a performance-first API and heavily optimized Zig-based JS/TS parser, Bun’s bundler is 1.75x faster than esbuild on esbuild’s three.js benchmark.
Bundle 10 copies of three.js from scratch with source maps and minification

Why migrate?

Here are some reasons you might want to migrate from esbuild to Bun’s bundler:

Speed

Bun’s bundler is significantly faster than esbuild, especially for large projects. The Zig-based implementation and careful optimizations make builds complete faster.

Native features

Bun includes native support for:
  • TypeScript and JSX: No configuration needed
  • CSS bundling: Built-in CSS processing with modern features
  • HTML processing: Bundle complete web applications
  • Macros: Run code at build time
  • Framework features: React Fast Refresh, server components

Unified toolchain

Bun provides a complete JavaScript runtime and toolkit:
  • Bundler
  • Runtime
  • Test runner
  • Package manager
Using Bun means fewer tools to install, configure, and maintain.

Modern defaults

Bun uses modern defaults:
  • ESM by default
  • Modern JavaScript syntax
  • Fast native loaders for common file types

CLI API

Both Bun and esbuild provide command-line interfaces.
In Bun’s CLI, simple boolean flags like --minify don’t accept arguments. Other flags with arguments like --outdir <path> accept arguments; these flags can be written as --outdir out or --outdir=out. Some flags like --define can be specified multiple times: --define foo=bar --define bar=baz.

Additional flags

JavaScript API

Plugin API

Bun’s plugin API is similar to esbuild’s but not identical. Both use onLoad and onResolve hooks, but the exact API differs:

esbuild

Bun

Key differences:
  • Bun requires explicit loader specification in onLoad
  • Bun supports additional lifecycle hooks: onStart, onEnd, onBeforeParse
  • Bun’s plugin system is shared between runtime and bundler
See Bundler > Plugins for complete documentation.

Migration checklist

  1. Update your build script
    • Change esbuild to bun build in CLI commands
    • Change esbuild.build() to Bun.build() in JavaScript
  2. Remove --bundle flag
    • Bun bundles by default
    • Add --no-bundle if you need transpilation only
  3. Update loader syntax
    • Change --loader:.svg=text to --loader .svg:text
  4. Update naming options
    • assetNames → naming.asset
    • chunkNames → naming.chunk
    • entryNames → naming.entry
  5. Update platform option
    • --platform → --target
  6. Check unsupported features
    • Remove --serve (use Bun.serve instead)
    • Remove --target (syntax downleveling not supported)
    • Remove --inject if used
  7. Update plugins
    • Review plugin API differences
    • Add explicit loader to onLoad returns
    • Test plugin behavior
  8. Test your build
    • Run the new build command
    • Verify output files
    • Test in browsers/environments

Example migration

Before (esbuild)

package.json

After (Bun)

package.json
That’s it! Most esbuild projects can be migrated with minimal changes.

Getting help

If you encounter issues during migration:
  1. Check the Bun documentation
  2. Search GitHub issues
  3. Ask in the Bun Discord
  4. File a bug report if you find a problem