---
title: "Node.js"
description: "Run libfx with a native addon or WebAssembly in Node.js."
canonical_url: https://fx.sh/docs/lib/node
markdown_url: https://fx.sh/docs/lib/node.md
---

# Node.js

The Node.js entry point runs the agent through a native addon, with WebAssembly as a fallback.

## Install

Use Node.js 20 or later:

```sh
npm install libfx@0.0.14
```

Follow [Quick start](https://fx.sh/docs/lib/quick-start.md) to connect a model and run your first prompt.

## Choose an entry point

| Import | Description | Environment |
| --- | --- | --- |
| `libfx` | The entry point for the current environment | Node or browser |
| `libfx/node` | Native addon first, WebAssembly fallback | Node |
| `libfx/browser` | WebAssembly | Browser |
| `libfx/wasm` | WebAssembly without packaged asset paths | Node or browser |
| `libfx/durable-local`, `libfx/durable-vercel`, `libfx/durable-world` | [Where sessions live](https://fx.sh/docs/lib/durability.md#where-sessions-live) | Node |
| `libfx/chatgpt`, `libfx/grok` | [Sign-in for ChatGPT and Grok plans](https://fx.sh/docs/lib/providers.md) | Node |
| `libfx/mcp`, `libfx/skills`, `libfx/skills/node` | [MCP](https://fx.sh/docs/lib/mcp.md) and [skills](https://fx.sh/docs/lib/skills.md) adapters | Node or browser; `skills/node` in Node or Bun |

Node applications can also use `require('libfx')`. With TypeScript's `moduleResolution: 'bundler'`, add `'node'` to `customConditions` to get the Node.js types.

## Choose a backend

`backend: 'auto'` is the default. It tries the native addon first and falls back to WebAssembly. Set `backend: 'native'` when you want the agent to fail if the addon is unavailable.

The package includes addons for Linux and macOS on x64 and arm64. Linux addons need glibc 2.34 or later. Windows uses the WebAssembly fallback. The native backend doesn't need JSPI or experimental Node flags; every WebAssembly path needs [JSPI](https://fx.sh/docs/lib/webassembly.md#check-runtime-support). On the native backend, the tool calls from one model response run at the same time.

The packaged native addon implements the agent's engine, so `createFxTerminal()` uses WebAssembly. See [the WebAssembly terminal](https://fx.sh/docs/lib/webassembly.md#embed-the-terminal) for that API and [AgentOptions](https://fx.sh/docs/lib/api.md#agentoptions) for supplying your own addon or WebAssembly asset.

<span id="nextjs-and-vercel" />

## Use the agent in a server route

Create the agent once at module scope, and use it from every route:

```js
// lib/agent.js
import { createFxAgent } from 'libfx'

export const agent = createFxAgent({ model: 'anthropic/claude-opus-5.5', tools })
```

Then return a session's stream from a route, as [Prompts and streaming](https://fx.sh/docs/lib/prompts.md#stream-to-a-browser) shows. Don't create or close an agent per request: the agent keeps running a turn after the response ends. On Vercel, add the queue route from [Durability](https://fx.sh/docs/lib/durability.md#on-vercel).

Native agents support Next.js 15 with webpack and Next.js 16 with webpack or Turbopack, including standalone builds. The package includes its native assets, so you don't need `serverExternalPackages` or manual file tracing. If you use WebAssembly in a standalone build, supply its assets yourself, because the standalone tracer leaves out `.wasm` files.

## Handle a missing backend

```js
import { getBackendInfo } from 'libfx'

const info = await getBackendInfo({ surface: 'agent', backend: 'auto' })
console.log(info.backend)
console.log(info.attempts)
```

`getBackendInfo()` checks whether the native addon or WebAssembly can load. It doesn't validate credentials or make a model request, though a remote WebAssembly asset may still need a fetch. Use `surface: 'terminal'` to check terminal support.

`LIBFX_JSPI_REQUIRED` means the WebAssembly path needs JSPI. On Node versions that need a flag, start with `node --experimental-wasm-jspi agent.mjs`. `LIBFX_NATIVE_UNAVAILABLE` means the native addon can't provide the requested agent or terminal. The attempts from [`getBackendInfo()`](https://fx.sh/docs/lib/api.md#getbackendinfo) tell missing files, unsupported platforms, and other loading failures apart.

## Migrating from 0.0.13

In libfx 0.0.13 and earlier, `createFxAgent()` created one in-memory conversation. That's now `createFxEngine()`, and `createFxAgent()` creates the durable agent:

- To keep the old behavior, rename `await createFxAgent(options)` to `await createFxEngine(options)`.
- To move to sessions, call `createFxAgent(options)` without `await`, then `agent.session().prompt()`.

Code written for 0.0.13 runs against the agent once its tools set `idempotent`, with a few differences: breaking out of a turn's events no longer cancels it, turns have no `cancel()` or `steer()` (the session does), and `persistence` and `sessionId` throw because the durability holds the session.

Three changes can break existing code:

- Every tool given to `createFxAgent()` must set `idempotent` to `true` or `false`. Without it, `createFxAgent()` throws an error that names the tool. See [Tools with effects](https://fx.sh/docs/lib/durability.md#tools-with-effects).
- A tool's `writes` now defaults to the opposite of `idempotent`, in `createFxEngine()` too, so a tool that isn't marked idempotent runs alone.
- A journal written by 0.0.14 can't be loaded by an older libfx, which fails with `FxJournalVersionError`.

## Migrating from 0.0.7

The agent API changed in 0.0.8, and again in 0.0.14. These steps lead to the 0.0.13 API; then follow [Migrating from 0.0.13](#migrating-from-0013):

- Pass `apiKey` and `model` directly instead of through `env`.
- Call `agent.prompt()` instead of `agent.createSession()` followed by `session.prompt()`.
- Save conversation checkpoints, and supply tools and instructions again when you restore.

For the old API, use the [0.0.7 SDK README](https://github.com/vercel-labs/fx/blob/cef08aa0f178537e552a931c7863dc4c1487e4a0/sdk/README.md).

<span id="run-a-headless-agent" />
<span id="save-and-restore-a-conversation" />
<span id="what-the-embedded-agent-can-do" />
<span id="add-tools" />
<span id="connect-mcp-and-skills" />
<span id="discover-models" />
<span id="security-boundaries" />

## Agent guides

- [Prompts and streaming](https://fx.sh/docs/lib/prompts.md)
- [Durability](https://fx.sh/docs/lib/durability.md)
- [Tools](https://fx.sh/docs/lib/tools.md)
- [Models](https://fx.sh/docs/lib/models.md) and [Providers](https://fx.sh/docs/lib/providers.md)
- [Save and restore](https://fx.sh/docs/lib/checkpoints.md)
- [MCP](https://fx.sh/docs/lib/mcp.md) and [Skills](https://fx.sh/docs/lib/skills.md)

---

[Browse all fx documentation](https://fx.sh/llms.txt)
