Today, we’re introducing a new SDK for React Flow that allows you to build
realtime multiplayer flowcharts in just a few lines of code, enabling
collaboration between humans and agents. It also enables powerful collaborative
features like live cursors, multiplayer undo/redo, and pinned comment threads.

<InstallCommand
  options={[
    { label: "npm", command: "npm install @liveblocks/react-flow" },
    { label: "yarn", command: "yarn add @liveblocks/react-flow" },
    { label: "pnpm", command: "pnpm add @liveblocks/react-flow" },
    { label: "bun", command: "bun add @liveblocks/react-flow" },
  ]}
/>

## Multiplayer React Flow

[React Flow](https://reactflow.dev/) is a customizable React component for
building node-based editors, workflows, and interactive diagrams. Our new
integration stores your flowchart state and synchronizes it between users in
realtime, allowing you to build new collaborative apps, or add multiplayer to
your existing ones.

<Figure>
  <MuxVideo
    playbackId="T762ah02HYZ01RQ9PGKpSccadfAC5GaRVrSG7xJb845BU"
    alt="Multiplayer React Flow with Liveblocks"
    static={true}
  />
</Figure>

To get started, connect to a multiplayer Liveblocks room, import
[`useLiveblocksFlow`](/docs/api-reference/liveblocks-react-flow/#useLiveblocksFlow),
and pass its properties to the `ReactFlow` component. Additionally, you can
render live presence cursors for each user by importing
[`Cursors`](/docs/api-reference/liveblocks-react-ui/#cursors).

```tsx
import { useLiveblocksFlow, Cursors } from "@liveblocks/react-flow/suspense";

function Flowchart() {
  const { nodes, edges, onNodesChange, onEdgesChange, onConnect } =
    useLiveblocksFlow();

  return (
    <ReactFlow
      nodes={nodes}
      edges={edges}
      onNodesChange={onNodesChange}
      onEdgesChange={onEdgesChange}
      onConnect={onConnect}
    >
      <Cursors />
    </ReactFlow>
  );
}
```

### Initial state

Your flowchart can start with an initial set of shapes and connections, which is
set by passing `nodes` and `edges` to `useLiveblocksFlow` as the first argument.

```tsx
const { nodes, edges /* ... */ } = useLiveblocksFlow({
  nodes: {
    initial: [
      // +++
      {
        id: "node-1",
        type: "input",
        data: { showPreview: true },
        position: { x: 250, y: 25 },
      },
      // +++
      // ...
    ],
  },

  edges: {
    initial: [
      // +++
      { id: "e1-2", source: "node-1", target: "node-2" },
      // +++
      // ...
    ],
  },
});
```

Learn more in our
[React Flow documentation](/docs/api-reference/liveblocks-react-flow).

### Custom nodes and local properties

You can define custom nodes in your React Flow app like normal, and `data` will
be automatically synchronized between users. However, you may wish for some
properties to be kept local and singleplayer. An example would be a
`showPreview` property, which might be used to toggle some kind of preview UI
inside a node.

To make a property like `showPreview` singleplayer only, add it to the `sync`
object, and set it to `false`.

```tsx
const { nodes, edges /* ... */ } = useLiveblocksFlow({
  nodes: {
    initial: [
      {
        id: "node-1",
        type: "input",
        data: { showPreview: true },
        position: { x: 250, y: 25 },
      },
      // ...
    ],

    // Keep `showPreview` local in "input" nodes
    // +++
    sync: {
      input: { showPreview: false },
    },
    // +++
  },

  edges: {
    /* ... */
  },
});
```

Find more information on
[custom nodes](/docs/api-reference/liveblocks-react-flow#custom-nodes) and
[local properties](/docs/api-reference/liveblocks-react-flow#sync-config).

## Infrastructure out of the box

React Flow is powered by
[Liveblocks Storage](/docs/collaboration-features/multiplayer/sync-engine/liveblocks-storage)
under the hood, our battle-tested sync engine and datastore, meaning you can
take advantage of its existing features right out of the box. On the front end,
one such feature is undo/redo, which extends React Flow’s existing
functionality.

<Figure>
  <MuxVideo
    playbackId="N6MpbTSZqJo3baKFLJVnLnOoguMrQ3eTPgpfNYix01MY"
    alt="Multiplayer undo/redo in React Flow"
    static={true}
  />
</Figure>

Multiplayer undo/redo is trivial to implement with the
[`useUndo`](/docs/api-reference/liveblocks-react/#useUndo) and
[`useRedo`](/docs/api-reference/liveblocks-react/#useRedo) hooks from
[`@liveblocks/react`](/docs/api-reference/liveblocks-react/).

```tsx
import { useUndo, useRedo } from "@liveblocks/react/suspense";

function Toolbar() {
  const undo = useUndo();
  const redo = useRedo();

  return (
    <div>
      <button onClick={undo}>↩️ Undo</button>
      <button onClick={redo}>↪️ Redo</button>
    </div>
  );
}
```

### Front end features

Around [100 React hooks](/docs/api-reference/liveblocks-react) with various
functionality are available, for example:

- [`useOthers`](/docs/api-reference/liveblocks-react#useOthers): Create live
  avatar stacks and custom presence.
- [`useThreads`](/docs/api-reference/liveblocks-react#useThreads): Add threaded
  commenting to your flow ([example](#collaborative-flowchart-builder)).
- [`useSyncStatus`](/docs/api-reference/liveblocks-react#useSyncStatus): Get
  React Flow sync status and show a spinner.
- [`useLostConnectionListener`](/docs/api-reference/liveblocks-react#LiveblocksProviderLostConnectionTimeout):
  Gracefully handle poor connections.
- [`useBroadcastEvent`](/docs/api-reference/liveblocks-react#useBroadcastEvent):
  Broadcast custom realtime events to connected users.

We also provide [React components](/docs/api-reference/liveblocks-react-ui),
[DevTools extensions](/docs/tools/devtools), and
[text editors](/docs/collaboration-features/multiplayer/text-editor).

### Back end features

On the back end, Liveblocks has a
[Node.js SDK](/docs/api-reference/liveblocks-node#Storage),
[REST API](/docs/api-reference/rest-api-endpoints#Storage), and
[webhooks](/docs/platform/webhooks#StorageUpdatedEvent), which allow you to
fetch and edit your React Flow state, and trigger events when it’s modified.

Alongside REST API functions and methods, you can also trigger changes when the
React Flow document is modified using our
[`storageUpdated` webhook](/docs/platform/webhooks#StorageUpdatedEvent).
Additionally, you can check your documents in the [dashboard](/dashboard), and
develop/test locally using our [dev server](/docs/tools/dev-server).

## Integrate realtime AI agents

Liveblocks allows AI agents to collaborate with other agents and humans in
realtime. Recently we released new APIs for presence which can be used to
display live AI cursors in your application, and combined with server-side
editing, you can create an AI agent that collaborates like a human.

<Figure>
  <MuxVideo
    playbackId="LwRVd01O6800xcQCSId0002nLbaWSW9wNOCdBJqx1AFFqVU"
    alt="AI agent editing a flowchart"
    static={true}
  />
</Figure>

### AI editing requires multiplayer

True conflict-resolved multiplayer is required for AI agents to edit
simultaneously with other users, otherwise changes will be lost. Liveblocks
Storage is a sync engine designed specifically for this use case, enabling
seamless editing.

<Figure>
  <MuxVideo
    playbackId="3ujpqoUlRZ7IhwogYWmygRDN02DZ2EerjuyHYM5zzh9c"
    alt="A human and AI agent simultaneously editing a flowchart"
    static={true}
  />
</Figure>

Multiple users can even edit the same node at the same time, and changes will be
merged and resolved automatically.

### Simple server-side editing

To update a React Flow diagram from your Node.js back end, use
[`mutateFlow`](/docs/api-reference/liveblocks-react-flow#mutateFlow). It opens a
room’s flow for reading and mutating, letting you work with familiar React Flow
nodes and edges without needing to deal with Liveblocks Storage primitives
directly.

```ts
import { Liveblocks } from "@liveblocks/node";
// +++
import { mutateFlow } from "@liveblocks/react-flow/node";
// +++

const client = new Liveblocks({ secret: "{{SECRET_KEY}}" });

await mutateFlow({ client, roomId: "my-room-id" }, (flow) => {
  flow.addNode({
    id: "node-3",
    type: "input",
    data: { showPreview: true },
    position: { x: 100, y: 50 },
  });

  flow.updateEdgeData("e2-3", {
    color: "#ff5349",
  });
});
```

This is ideal for building AI agents that edit flowcharts in realtime alongside
human users. Learn more in our
[server-side React Flow documentation](/docs/api-reference/liveblocks-react-flow#server-side).

## Examples

We’ve created three new examples to help you get started with React Flow and
Liveblocks. Try the live demos below.

### Collaborative flowchart builder

A flowchart builder that allows you to place different elements on the page.
Elements’ colors and shapes can be changed, and connections can be made between
them. It also features comment pins, undo/redo, and live cursors.

<Figure
  caption={
    <>
      Our{" "}
      <Link href="/examples/collaborative-flowchart-builder/nextjs-flowchart-builder">
        Collaborative Flowchart Builder
      </Link>{" "}
      example
    </>
  }
>
  <Embed
    src="https://nextjs-flowchart-builder.liveblocks.app"
    className="aspect-16/10 w-full bg-white"
  />
</Figure>

### Collaborative flowchart AI

A flowchart builder similar to the previous example, but with an AI editing
dialog box. Try asking it to “make the chart horizontal” to watch it work.

<Figure
  caption={
    <>
      Our{" "}
      <Link href="/examples/collaborative-flowchart-ai/nextjs-react-flow-ai">
        Collaborative Flowchart AI
      </Link>{" "}
      example
    </>
  }
>
  <Embed
    src="https://nextjs-react-flow-ai.liveblocks.app"
    className="aspect-16/10 w-full bg-white"
  />
</Figure>

### Collaborative flowchart

A basic read-only setup with collaborative editing and a custom interactive
node.

<Figure
  caption={
    <>
      Our{" "}
      <Link href="/examples/collaborative-flowchart/nextjs-react-flow">
        Collaborative Flowchart
      </Link>{" "}
      example
    </>
  }
>
  <Embed
    src="https://nextjs-react-flow.liveblocks.app"
    className="aspect-16/10 w-full bg-white"
  />
</Figure>

## Get started now

To get started with React Flow, follow our new quickstart guide for Next.js.

<ButtonLink href="/docs/get-started/nextjs-react-flow" size="lg">
  Get started now
</ButtonLink>

## Contributors

<Contributors gitHubUsernames={["sugardarius", "marcbouchenoire", "nvie"]} />