lively

Multiplayer in eight lines.

Presence, live cursors and CRDT storage over one WebSocket. 41 React hooks, and a server you run yourself.

bun add @waits/lively-react
Read the docs →
Canvas.tsxoffline
import { RoomProvider, useOthers } from "@waits/lively-react";
function Canvas() {
const others = useOthers();
return <CursorOverlay peers={others} />;
}
<RoomProvider roomId="board-1" initialStorage={{ shapes: [] }}>
<Canvas />
</RoomProvider>

Every example runs. Copy the one you need.

The previews below are scripted so they behave the same every time. The six links further down are the real thing, running on the same server.

shape
Scripted replay
Live cursors
const others = useOthers();
const [, update] = useMyPresence();

function onPointerMove(e) {
  update({ cursor: { x: e.clientX, y: e.clientY } });
}
  • Wire up the room provider
  • Add cursor overlay
Scripted replay
Shared state
const todos = useStorage((root) => root.get("todos"));

const addTodo = useMutation(({ storage }, text) => {
  storage.root.get("todos").push({ text, done: false });
}, []);

Run the server yourself.

One command starts it. No account, no dashboard, no egress bill.

$ npx lively dev
Lively dev server on :1999
$ npx lively rooms list
board-1 · landing · todo-default
$ npx lively rooms inspect board-1
shapes: LiveList(4)