esbuild

Fast bundling with esbuild transformer

esbuild Transformer

The esbuild transformer is the recommended choice for most Packem projects. Written in Go, it offers the best balance of speed, TypeScript support, and stability.

Overview

This example shows how to build a TypeScript library using the esbuild transformer and how to tune the esbuild-specific options that Packem exposes through rollup.esbuild.

esbuild handles:

  • TypeScript and modern JavaScript transformation (type stripping, down-leveling)
  • JSX (React, Preact, and other runtimes)
  • Tree shaking and source maps

esbuild transforms each file as it passes through Rollup (the default bundler). Type checking is not performed during transformation — run tsc --noEmit separately for type validation.

When to Use

  • Most TypeScript and JavaScript libraries
  • React applications and component libraries
  • Large codebases that need fast rebuilds in watch mode

Project Setup

Directory Structure

my-lib/
├── src/
│   └── index.ts
├── package.json
├── packem.config.ts
└── tsconfig.json

Packem Configuration

The transformer is selected by importing it and assigning it to transformer. esbuild-specific options live under rollup.esbuild:

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      // Optionally preserve symbol names during minification
      // (off by default — opt in only if you rely on runtime name reflection)
      keepNames: true,
      // Override the character set of the output
      charset: 'utf8',
      // Map custom extensions to esbuild loaders
      loaders: {
        '.json': 'json'
      }
    }
  }
})

target is resolved automatically from your tsconfig.json compilerOptions.target and the build runtime, so you usually do not need to set it manually. You can still override it via rollup.esbuild.target.

Minimal Configuration

When you do not need to customize anything, the transformer alone is enough — Packem provides sensible esbuild defaults (JSX from your tsconfig, tree shaking, smaller source maps):

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer
})

Building

packem build

Notes

  • keepNames defaults to false. It wraps every named function/closure in an Object.defineProperty call, which can slow down closure-heavy code in published builds — opt in only when you need runtime .name reflection.
  • keepNames is also forced off automatically when minification is disabled or the tsconfig target is es5, because combining it with repeated transforms breaks tree shaking.
  • Source maps follow the top-level sourcemap option; esbuild's sourcesContent is disabled by default to keep maps small.
  • esbuild does not type-check. Pair it with tsc --noEmit in CI for type safety.
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues