esbuild-wasm: WebAssembly Bundler
esbuild-wasm is the WebAssembly-based distribution of esbuild, a high-performance JavaScript and TypeScript bundler and minifier. It provides the core bundling and transformation capabilities of esbuild in a cross-platform WebAssembly binary, suitable for environments like web browsers, Deno, and Bun, or Node.js where a native binary might not be ideal or available. The current stable version is v0.28.0. The project maintains a rapid release cadence, often introducing new features and bug fixes, and sometimes includes deliberate backwards-incompatible changes, as highlighted in releases like v0.27.0. Its key differentiator from the primary `esbuild` package is its WebAssembly implementation, offering broader environment compatibility, though it might have slight performance variations compared to the native binary. Users should be aware of the explicit `initialize` step required for its operation.
Common errors
-
Error: Must call "initialize" before "build" or "transform"
cause The WebAssembly module has not been loaded and initialized, or `initialize()` was not awaited.fixEnsure `await initialize({ worker: true, wasmURL: '...' });` is called and successfully completes before any `build` or `transform` operations. -
ReferenceError: require is not defined
cause Attempting to use `require()` in an ES module context (e.g., a `.mjs` file or a file in a `"type": "module"` package) or browser environment.fixUse `import { build } from 'esbuild-wasm';` syntax in ES module files. If targeting a browser, ensure your bundler processes `esbuild-wasm` correctly. -
TypeError: esbuild.build is not a function
cause Incorrectly attempting to access `build` from a default import or a non-destructured `require` call when `build` is a named export.fixFor ESM, use `import { build } from 'esbuild-wasm';`. For CJS, use `const { build } = require('esbuild-wasm');` to destructure named exports.
Warnings
- breaking esbuild and esbuild-wasm can introduce backwards-incompatible changes even in minor versions. Release v0.27.0 explicitly noted this and advised pinning exact versions.
- gotcha The `esbuild-wasm` package requires explicit initialization via `initialize()` before any other API calls (like `build` or `transform`). Failing to do so will result in an error.
- gotcha While `esbuild-wasm` offers broad environment compatibility, it is generally much slower (potentially 10x slower) than the native `esbuild` package, especially in Node.js environments.
- gotcha Recent `esbuild` releases, such as v0.28.0, add support for new web standards like `with { type: 'text' }` imports. While beneficial, ensure your target environments and tooling are compatible if relying on such features.
Install
-
npm install esbuild-wasm -
yarn add esbuild-wasm -
pnpm add esbuild-wasm
Imports
- initialize
import esbuild from 'esbuild-wasm'; // esbuild-wasm does not have a default export.
import { initialize } from 'esbuild-wasm' - transform
const transform = require('esbuild-wasm').default.transform; // esbuild-wasm does not export a default in CJS.import { transform } from 'esbuild-wasm' - build
import { build } from 'esbuild-wasm/lib/main'; // Incorrect submodule path; use the main package export.import { build } from 'esbuild-wasm' - BuildOptions
import { BuildOptions } from 'esbuild-wasm'; // BuildOptions is a TypeScript type, not a runtime value.import type { BuildOptions } from 'esbuild-wasm'
Quickstart
import { initialize, transform } from 'esbuild-wasm';
async function runWasmEsbuild() {
// esbuild-wasm requires initialization to load the WebAssembly binary.
// This should only be called once. For Node.js, setting 'worker: true'
// and explicitly providing wasmURL is robust for predictable loading.
await initialize({
worker: true,
wasmURL: 'https://unpkg.com/esbuild-wasm@0.28.0/esbuild.wasm' // Specify a CDN URL for predictability
});
const sourceCode = `
import { someHelper } from './utils';
const message: string = "Hello, esbuild-wasm!";
console.log(message + someHelper());
function someHelper() {
return " from a helper!";
}
`;
console.log('Original code:\n', sourceCode);
// Transform TypeScript code to JavaScript, minifying it.
const result = await transform(sourceCode, {
loader: 'ts',
minify: true,
sourcemap: true,
target: 'es2018',
});
console.log('\nTransformed code:');
console.log(result.code);
console.log('\nSourcemap:');
console.log(result.map);
// When using worker: true, the worker process typically exits with the main process.
// Explicit 'stop' is usually not needed unless managing a long-lived service manually.
}
runWasmEsbuild().catch(console.error);