evanw/esbuild · error · Error
The "transformSync" API only works in node
Error message
The "transformSync" API only works in node
What it means
The browser entry of esbuild (lib/npm/browser.ts) defines transformSync as a stub that always throws. The WebAssembly-backed browser build cannot run synchronously, so esbuild blocks the call rather than pretending to work.
Solutions
- Use esbuild.transform(...) and await the returned promise.
- Switch to the native esbuild package running under node if synchronous execution is required.
- Make the calling code async-compatible.
Example fix
// before
const out = esbuild.transformSync(code, { loader: 'ts' })
// after
const out = await esbuild.transform(code, { loader: 'ts' }) Defensive patterns
Strategy: validation
Validate before calling
// Guard against the browser sync stub by using the async transform.
const isBrowserBuild =
typeof window !== 'undefined' && typeof window.document !== 'undefined'
const out = isBrowserBuild
? await esbuild.transform(code, { loader: 'ts' })
: esbuild.transformSync(code, { loader: 'ts' }) Prevention
- Default to esbuild.transform(...) (async) for code that may run in browsers.
- Reserve transformSync for node-only code paths.
- Centralize transform calls behind an async wrapper.
When it happens
Trigger: Application code calls esbuild.transformSync(input, options) while the resolved module is the browser build (esbuild-wasm or the package 'browser' field).
Common situations: Copy-pasting node-oriented esbuild usage into a browser bundle; sharing a transform helper module across node and browser targets.
Related errors
- The "analyzeMetafileSync" API only works in node
- The "buildSync" API only works in node
- The "formatMessagesSync" API only works in node
- You need to wait for the promise returned from "initialize"…
- Cannot use the "serve" API in this environment
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/0784f91e3a967515.
Report an issue: GitHub.
Appendix: source
Thrown at lib/npm/browser.ts:37
export let context: typeof types.context = (options: types.BuildOptions) =>
ensureServiceIsRunning().context(options)
export const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>
ensureServiceIsRunning().transform(input, options)
export const formatMessages: typeof types.formatMessages = (messages, options) =>
ensureServiceIsRunning().formatMessages(messages, options)
export const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>
ensureServiceIsRunning().analyzeMetafile(metafile, options)
export const buildSync: typeof types.buildSync = () => {
throw new Error(`The "buildSync" API only works in node`)
}
export const transformSync: typeof types.transformSync = () => {
throw new Error(`The "transformSync" API only works in node`)
}
export const formatMessagesSync: typeof types.formatMessagesSync = () => {
throw new Error(`The "formatMessagesSync" API only works in node`)
}
export const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {
throw new Error(`The "analyzeMetafileSync" API only works in node`)
}
export const stop = () => {
if (stopService) stopService()
return Promise.resolve()
}
interface Service {
build: typeof types.build
context: typeof types.contextView on GitHub (pinned to f6058f8364)