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
serve() spins up an HTTP server inside esbuild's native binary that serves built output and (optionally) a static servedir. Like watch(), it depends on the Go binary binding to a network socket and a filesystem; in browser/wasm builds (hasFS:false) the guard at lib/shared/common.ts:1080 throws. The wasm runtime has no socket layer to bind.
Source
Thrown at lib/shared/common.ts:1080
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 = hostView on GitHub (pinned to 6ff1d8b0d8)
Solutions
- Run serve() under the Node or Deno native entry (hasFS:true).
- In the browser, serve output yourself by reading result.outputFiles and feeding them to your own HTTP layer, or skip the dev-server pattern.
- If you only need to inspect output, drop serve() and use build({ write:false }) then read outputFiles.
Example fix
// before (browser wasm)
const ctx = await esbuild.context({ entryPoints: ['app.ts'] });
await ctx.serve({ servedir: '.', port: 8000 });
// after — run under node, or fetch output manually
const res = await esbuild.build({ entryPoints: ['app.ts'], write: false });
serveMyself(res.outputFiles); // your own server Defensive patterns
Strategy: validation
Validate before calling
const hasFS = typeof process !== 'undefined' && !!process.versions?.node;
if (hasFS) {
await ctx.serve({ port: 8000, servedir: '.' });
} else {
throw new Error('serve() not available in this environment; use Node');
} Type guard
function canServe(): boolean {
return typeof process !== 'undefined' && typeof process.versions?.node === 'string';
} Try / catch
try {
await ctx.serve(opts);
} catch (e) {
if (/Cannot use the "serve" API/.test(e.message)) {
// fall back to reading outputFiles and serving yourself
} else throw e;
} Prevention
- Reserve serve() for the Node/Deno native entry.
- In browser bundlers, expose outputFiles via your own HTTP layer.
- Annotate shared configs with the host they target.
When it happens
Trigger: Calling ctx.serve({ port: 8000, servedir: '.' }) on a context from esbuild-wasm or the browser entrypoint. Calling serve() in Deno wasm mode.
Common situations: Building an in-browser IDE and wanting a 'preview server'. Migrating a Node dev-server script that mixed build + serve into a worker. Trying to serve files from inside a sandboxed edge function.
Related errors
- The "write" option is unavailable in this environment
- Cannot use the "watch" API in this environment
- Invalid serve path: %s
- Invalid fallback path: %s
- The "serve" API is not supported when using WebAssembly
AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03).
Data as JSON: /data/errors/5207af9be95e6319.json.
Report an issue: GitHub.