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
- Use the native node esbuild package so `serve()` is available (`hasFS` is true).
- In the browser, run your own HTTP server or serve the `outputFiles` from the build result through your own hosting layer.
- 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
- Run your own HTTP server for browser contexts.
- Gang serve() behind a Node-only code path to avoid importing it in the browser bundle.
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
- Cannot use the "watch" API in this environment
- The "write" option is unavailable in this environment
- Cannot compute relative path from
- Failed to download
- Invalid fallback path
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 = hostView on GitHub (pinned to f6058f8364)