evanw/esbuild · error

The "serve" API is not supported when using WebAssembly

Error message

The "serve" API is not supported when using WebAssembly

What it means

The serve API (ctx.serve()) is intentionally stripped from the WebAssembly build of esbuild to save approximately 2.7MB of binary size. The serve_wasm.go file replaces the Serve method with a stub that always returns this error. This is a compile-time platform restriction, not a runtime misconfiguration.

Solutions

  1. Use the native 'esbuild' package instead of 'esbuild-wasm' if you need serve mode
  2. Implement your own HTTP server that wraps esbuild-wasm's build() output
  3. Detect the wasm environment at runtime and skip serve calls, providing an alternative dev server

Example fix

// before
import * as esbuild from 'esbuild-wasm'
const ctx = await esbuild.context(opts)
await ctx.serve({ port: 8000 })
// after
import * as esbuild from 'esbuild'
const ctx = await esbuild.context(opts)
await ctx.serve({ port: 8000 })
Defensive patterns

Strategy: type-guard

Validate before calling

import * as esbuildNative from 'esbuild'
import * as esbuildWasm from 'esbuild-wasm'
const isWasm = typeof WebAssembly !== 'undefined' && typeof window !== 'undefined'
const esbuild = isWasm ? esbuildWasm : esbuildNative
if (isWasm) {
  console.warn('Serve API is not available in the WebAssembly build')
}

Type guard

function isServeSupported(esbuildModule) {
  // The wasm build stubs Serve to always error; check by feature-detecting
  return typeof esbuildModule.serve !== 'undefined' &&
    esbuildModule.toString().indexOf('wasm') === -1
}
// Or detect the wasm package directly:
const isWasmBuild = esbuild.versions?.wasm === true

Try / catch

try {
  await ctx.serve(serveOptions)
} catch (e) {
  if (e.message.includes('not supported when using WebAssembly')) {
    console.warn('Serve not available in WASM; falling back to manual server')
    // implement alternative dev server
  } else {
    throw e
  }
}

Prevention

When it happens

Trigger: Using the esbuild-wasm package and calling ctx.serve(...) on a context created via esbuild-wasm's context() function.

Common situations: Switching from the native 'esbuild' package to 'esbuild-wasm' for browser/wasm compatibility without updating code that calls serve(), or environments that require the wasm build but still reference serve mode.

Related errors


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

Appendix: source

Thrown at pkg/api/serve_wasm.go:11

//go:build js && wasm
// +build js,wasm

package api

import "fmt"

// Remove the serve API in the WebAssembly build. This removes 2.7mb of stuff.

func (*internalContext) Serve(ServeOptions) (ServeResult, error) {
	return ServeResult{}, fmt.Errorf("The \"serve\" API is not supported when using WebAssembly")
}

type apiHandler struct {
}

func (*apiHandler) broadcastBuildResult(BuildResult, map[string]string) {
}

func (*apiHandler) stop() {
}

View on GitHub (pinned to f6058f8364)