evanw/esbuild · error · Error

Cannot use the "serve" API in this environment

Error message

Cannot use the "serve" API in this environment

What it means

Thrown by the context's `serve()` method (lib/shared/common.ts:1084) when `streamIn.hasFS` is false. The serve API starts a local HTTP server that serves built files and a directory of static assets, which requires filesystem access. It is therefore disabled in the browser/WASM build (`hasFS: false`).

Solutions

  1. Use the native node esbuild package so `serve()` is available (`hasFS` is true).
  2. In the browser, run your own HTTP server or serve the `outputFiles` from the build result through your own hosting layer.
  3. Gate the `serve()` call behind a Node-only code path.

Example fix

// before (browser/wasm)
const ctx = await esbuild.context(opts);
await ctx.serve({ servedir: '.', port: 8000 });
// after — host outputs yourself
const result = await esbuild.build({ ...opts, write: false });
// serve result.outputFiles via your own server/handler
Defensive patterns

Strategy: validation

Validate before calling

const canServe = typeof process !== 'undefined' && !!process.versions && !!process.versions.node;
if (canServe) await ctx.serve(serveOpts); else { /* host outputs yourself */ }

Type guard

function supportsServe(): boolean {
  return typeof process !== 'undefined' && !!process.versions && !!process.versions.node;
}

Prevention

When it happens

Trigger: Calling `context.serve({ port, servedir, ... })` on a context created through the browser/WASM esbuild API.

Common situations: Reusing a Node dev-server config (that calls `serve()`) with the WASM build; building an in-browser bundler playground and attempting to start esbuild's built-in server.

Related errors


AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09). Data as JSON: /api/errors/5207af9be95e6319. Report an issue: GitHub.

Appendix: source

Thrown at lib/shared/common.ts:1084

        watch: (options = {}) => new Promise((resolve, reject) => {
          if (!streamIn.hasFS) throw new Error(`Cannot use the "watch" API in this environment`)
          const keys: OptionKeys = {}
          const delay = getFlag(options, keys, 'delay', mustBeInteger)
          checkForInvalidFlags(options, keys, `in watch() call`)
          const request: protocol.WatchRequest = {
            command: 'watch',
            key: buildKey,
          }
          if (delay) request.delay = delay
          sendRequest<protocol.WatchRequest, null>(refs, request, error => {
            if (error) reject(new Error(error))
            else resolve(undefined)
          })
        }),

        serve: (options = {}) => new Promise((resolve, reject) => {
          if (!streamIn.hasFS) throw new Error(`Cannot use the "serve" API in this environment`)
          const keys: OptionKeys = {}
          const port = getFlag(options, keys, 'port', mustBeValidPortNumber)
          const host = getFlag(options, keys, 'host', mustBeString)
          const servedir = getFlag(options, keys, 'servedir', mustBeString)
          const keyfile = getFlag(options, keys, 'keyfile', mustBeString)
          const certfile = getFlag(options, keys, 'certfile', mustBeString)
          const fallback = getFlag(options, keys, 'fallback', mustBeString)
          const cors = getFlag(options, keys, 'cors', mustBeObject)
          const onRequest = getFlag(options, keys, 'onRequest', mustBeFunction)
          checkForInvalidFlags(options, keys, `in serve() call`)

          const request: protocol.ServeRequest = {
            command: 'serve',
            key: buildKey,
            onRequest: !!onRequest,
          }
          if (port !== void 0) request.port = port
          if (host !== void 0) request.host = host

View on GitHub (pinned to f6058f8364)