WebAssembly SDK

fx is written in Zig and builds as a native executable or WebAssembly. The experimental WebAssembly SDK runs the WebAssembly build from JavaScript as an interactive terminal or a headless ACP agent. The terminal API runs in browsers, while the headless API also runs in Node.js with JSPI enabled.

The try page runs the terminal WebAssembly build of fx.

The SDK is not published to npm. Follow the repository setup instructions to use it from source.

Choose a WebAssembly API

GoalAPIArtifact
Add the interactive fx terminalcreateFxTerminal()fx-term.wasm
Build your own interfacecreateFxAgent()fx-core.wasm

createFxTerminal() renders fx through a terminal component such as xterm.js. createFxAgent() exposes fx sessions through a JavaScript API backed by Agent Client Protocol (ACP).

Check runtime support

The SDK requires JavaScript Promise Integration (JSPI). Chrome and Edge include JSPI starting in version 137. WebKit added it in Safari 27 and Safari Technology Preview 238. In Node.js 24, enable it with --experimental-wasm-jspi. Call supportsJspi() before loading WebAssembly instead of checking the runtime name or version.

Embed the terminal

Install xterm.js for the terminal interface:

npm install @xterm/xterm

The example below assumes fx-sdk.js and fx-term.wasm are served from the same directory:

<div id="terminal" style="height: 600px"></div>
import { Terminal } from '@xterm/xterm'
import '@xterm/xterm/css/xterm.css'
import { createFxTerminal, supportsJspi, xtermAdapter } from './fx-sdk.js'

const container = document.querySelector('#terminal')

if (!(container instanceof HTMLElement)) {
  throw new Error('Missing #terminal element')
}

if (!supportsJspi()) {
  throw new Error('fx requires JSPI support')
}

const terminal = new Terminal()
terminal.open(container)

const runtime = await createFxTerminal({
  wasm: './fx-term.wasm',
  terminal: xtermAdapter(terminal),
})

runtime.exited.then((exitCode) => {
  console.log(`fx exited with code ${exitCode}`)
})

createFxTerminal() returns after fx starts. Use the returned write(), resize(), and abort() methods to control the terminal. The exited promise resolves when fx stops.

Run a headless agent

Use createFxAgent() when your app renders its own interface. This example passes an AI Gateway key for local development:

import { createFxAgent, supportsJspi } from './fx-sdk.js'

if (!supportsJspi()) {
  throw new Error('fx requires JSPI support')
}

const agent = await createFxAgent({
  wasm: './fx-core.wasm',
  env: {
    AI_GATEWAY_API_KEY: 'your_ai_gateway_api_key_here',
  },
})

const session = await agent.createSession()
const turn = session.prompt('Explain this project')

for await (const update of turn) {
  if (update.sessionUpdate === 'agent_message_chunk') {
    console.log(update.content.text)
  }
}

const { stopReason } = await turn.result
console.log(stopReason)

await agent.close()

Do not embed a long-lived API key in client code. For production, proxy AI Gateway requests through your backend. The terminal can also use the device login flow described in Browser integration.

Add persistence, login, and commands

The SDK can use your app's storage, authentication, and command execution. See Browser integration for configuration, prompt history, sessions, device login, and the optional workspace adapter.

WebAssembly runtime limits

The WebAssembly SDK does not include:

  • Native processes, operating-system sandboxing, keychain access, or arbitrary WASI filesystem access.
  • Native Model Context Protocol (MCP), subagents, skills, web search, auto-upgrade, or clipboard integration.
  • Tools supplied by the native fx runtime. The optional workspace adapter adds only run_command, implemented by your app.