{"id":"06bc8c354ccf15b7","repo":"evanw/esbuild","slug":"the-buildsync-api-only-works-in-node","errorCode":null,"errorMessage":"The \"buildSync\" API only works in node","messagePattern":"The \"buildSync\" API only works in node","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/npm/browser.ts","lineNumber":33,"sourceCode":"export let version = ESBUILD_VERSION\n\nexport let build: typeof types.build = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().build(options)\n\nexport let context: typeof types.context = (options: types.BuildOptions) =>\n  ensureServiceIsRunning().context(options)\n\nexport const transform: typeof types.transform = (input: string | Uint8Array, options?: types.TransformOptions) =>\n  ensureServiceIsRunning().transform(input, options)\n\nexport const formatMessages: typeof types.formatMessages = (messages, options) =>\n  ensureServiceIsRunning().formatMessages(messages, options)\n\nexport const analyzeMetafile: typeof types.analyzeMetafile = (metafile, options) =>\n  ensureServiceIsRunning().analyzeMetafile(metafile, options)\n\nexport const buildSync: typeof types.buildSync = () => {\n  throw new Error(`The \"buildSync\" API only works in node`)\n}\n\nexport const transformSync: typeof types.transformSync = () => {\n  throw new Error(`The \"transformSync\" API only works in node`)\n}\n\nexport const formatMessagesSync: typeof types.formatMessagesSync = () => {\n  throw new Error(`The \"formatMessagesSync\" API only works in node`)\n}\n\nexport const analyzeMetafileSync: typeof types.analyzeMetafileSync = () => {\n  throw new Error(`The \"analyzeMetafileSync\" API only works in node`)\n}\n\nexport const stop = () => {\n  if (stopService) stopService()\n  return Promise.resolve()\n}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/lib/npm/browser.ts#L15-L51","documentation":"esbuild's browser build (`lib/npm/browser.ts`) exports `buildSync` as a function that always throws. The synchronous API exists only on the Node entry point because it relies on `child_process.execFileSync` to run the native binary and block the event loop, which is impossible in a browser main thread. Importing `esbuild` and calling `buildSync` means you are resolving the browser build.","triggerScenarios":"Calling `esbuild.buildSync(options)` after `esbuild` has resolved to `lib/npm/browser.ts` — typically because a bundler (webpack/vite/esbuild itself) targeted the browser field, or because code ran in a browser/worker context.","commonSituations":"Using esbuild inside a browser-targeted webpack/vite build; importing esbuild in an isomorphic code path that runs in the browser; tooling that auto-selects the `browser` field of package.json; running esbuild in a Cloudflare Worker or Deno browser-like environment.","solutions":["Switch to the async `esbuild.build()` (returns a Promise) which is supported in the browser via the wasm service.","Ensure your bundler does not rewrite esbuild to its browser build — mark esbuild as external if you intend to use it only in Node.","If you genuinely need esbuild in the browser, use the `esbuild-wasm` package and call `initialize({ wasmURL })` before async APIs.","Move the `buildSync` call to a Node-only entry point that is never loaded in the browser bundle."],"exampleFix":"// before\nconst result = esbuild.buildSync({ entryPoints: ['a.ts'], bundle: true })\n\n// after\nconst result = await esbuild.build({ entryPoints: ['a.ts'], bundle: true })","handlingStrategy":"validation","validationCode":"const isBrowser = typeof window !== 'undefined' || typeof self !== 'undefined'\nif (isBrowser && typeof (esbuild as any).buildSync === 'function') {\n  // will throw — switch to async build\n}\n// Prefer: detect before invoking\nfunction safeBuild(opts) {\n  return isBrowser ? esbuild.build(opts) : Promise.resolve(esbuild.buildSync(opts))\n}","typeGuard":"function supportsSyncApi(): boolean {\n  return typeof process !== 'undefined' && !!process.versions?.node && typeof window === 'undefined'\n}","tryCatchPattern":"try {\n  const r = esbuild.buildSync(opts)\n} catch (e) {\n  if (/only works in node/.test(String((e as Error).message))) {\n    return await esbuild.build(opts) // graceful async fallback\n  }\n  throw e\n}","preventionTips":["Mark esbuild external in browser-targeted bundlers.","Prefer async esbuild.build() everywhere for cross-runtime portability.","Gate sync calls behind a Node environment check.","Document which entry points are Node-only."],"tags":["browser","sync-api","node-only","configuration"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}