{"id":"31c34a781859af71","repo":"evanw/esbuild","slug":"the-esbuild-javascript-api-cannot-be-bundled-plea","errorCode":null,"errorMessage":"The esbuild JavaScript API cannot be bundled. Please mark the \"esbuild\" package as external so it's not included in the bundle.\n\nMore information: The file containing the code for esbuild's JavaScript API (${__filename}) does not appear to be inside the esbuild package on the file system, which usually means that the esbuild package was bundled into another file. This is problematic because the API needs to run a binary executable inside the esbuild package which is located using a relative path from the API code to the executable. If the esbuild package is bundled, the relative path will be incorrect and the executable won't be found.","messagePattern":"The esbuild JavaScript API cannot be bundled\\. Please mark the \"esbuild\" package as external so it's not included in the bundle\\.\n\nMore information: The file containing the code for esbuild's JavaScript API \\(\\$\\{__filename\\}\\) does not appear to be inside the esbuild package on the file system, which usually means that the esbuild package was bundled into another file\\. This is problematic because the API needs to run a binary executable inside the esbuild package which is located using a relative path from the API code to the executable\\. If the esbuild package is bundled, the relative path will be incorrect and the executable won't be found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"lib/npm/node.ts","lineNumber":55,"sourceCode":"    +major < 12 || (+major === 12 && +minor < 17)\n\n    // >=v13.0.0 && <v13.13.0 also does not work\n    || (+major === 13 && +minor < 13)\n  ) {\n    worker_threads = void 0\n  }\n}\n\n// This should only be true if this is our internal worker thread. We want this\n// library to be usable from other people's worker threads, so we should not be\n// checking for \"isMainThread\".\nlet isInternalWorkerThread = worker_threads?.workerData?.esbuildVersion === ESBUILD_VERSION\n\nlet esbuildCommandAndArgs = (): [string, string[]] => {\n  // Try to have a nice error message when people accidentally bundle esbuild\n  // without providing an explicit path to the binary, or when using WebAssembly.\n  if ((!ESBUILD_BINARY_PATH || WASM) && (path.basename(__filename) !== 'main.js' || path.basename(__dirname) !== 'lib')) {\n    throw new Error(\n      `The esbuild JavaScript API cannot be bundled. Please mark the \"esbuild\" ` +\n      `package as external so it's not included in the bundle.\\n` +\n      `\\n` +\n      `More information: The file containing the code for esbuild's JavaScript ` +\n      `API (${__filename}) does not appear to be inside the esbuild package on ` +\n      `the file system, which usually means that the esbuild package was bundled ` +\n      `into another file. This is problematic because the API needs to run a ` +\n      `binary executable inside the esbuild package which is located using a ` +\n      `relative path from the API code to the executable. If the esbuild package ` +\n      `is bundled, the relative path will be incorrect and the executable won't ` +\n      `be found.`)\n  }\n\n  if (WASM) {\n    return ['node', [path.join(__dirname, '..', 'bin', 'esbuild')]]\n  } else {\n    const { binPath, isWASM } = generateBinPath()\n    if (isWASM) {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/lib/npm/node.ts#L37-L73","documentation":"`esbuildCommandAndArgs` (`node.ts:54`) detects when esbuild's own JS API file is no longer located at `<pkg>/lib/main.js` — meaning a bundler has inlined esbuild into another file. Since esbuild locates its native binary via a relative path from its source file, bundling breaks the path lookup and the binary can't be found. The throw happens at first API use (e.g. `build`, `transform`).","triggerScenarios":"Bundling the `esbuild` package into a single file (webpack/vite/rollup/esbuild-itself) without marking it external, then importing the bundled result. The check `path.basename(__filename) !== 'main.js' || path.basename(__dirname) !== 'lib'` is true because the bundled file lives elsewhere.","commonSituations":"Authoring a CLI or library that uses esbuild and shipping it as a bundle without `external: ['esbuild']`; a serverless function bundler that includes all deps; a monorepo build pipeline that bundles shared tools; mistakenly running esbuild through itself for deployment.","solutions":["Mark esbuild as external in your bundler config: webpack `externals`, rollup `external`, esbuild `external: ['esbuild']`, vite `build.rollupOptions.external`.","Use the `ESBUILD_BINARY_PATH` env var to point esbuild at its native binary explicitly (this also short-circuits the bundle detection in `esbuildCommandAndArgs`).","Don't bundle esbuild at all — leave it as a runtime dependency resolved from `node_modules`.","If you must ship a single file, switch to `esbuild-wasm` and bundle the wasm separately."],"exampleFix":"// before (esbuild bundling itself)\nawait esbuild.build({\n  entryPoints: ['src/cli.ts'],\n  bundle: true,\n  // esbuild gets inlined -> runtime error\n})\n\n// after\nawait esbuild.build({\n  entryPoints: ['src/cli.ts'],\n  bundle: true,\n  external: ['esbuild'],\n})","handlingStrategy":"validation","validationCode":"import { basename, dirname } from 'path'\nfunction isEsbuildBundled(): boolean {\n  // Reuses esbuild's own heuristic: API file must live at <pkg>/lib/main.js\n  return !(basename(__filename) === 'main.js' && basename(dirname(__filename)) === 'lib')\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always add 'esbuild' to your bundler's external list.","If you must bundle, set ESBUILD_BINARY_PATH so esbuild skips path-based detection.","Prefer esbuild-wasm (with separate wasm bundling) for fully self-contained bundles.","Smoke-test the bundled output by invoking build/transform once in CI."],"tags":["bundler","external","configuration","webpack","vite","rollup","native-binary"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}