Add multiplayer to any React app
in one line
Shared state that feels like useState, but multiplayer.
Built on Yjs. Self-host or use YSDK Cloud.
npm install @ysdk/react
import { YSDKProvider, useShared } from '@ysdk/react'
function App() {
return (
<YSDKProvider cloud={{ apiKey: "ysdk_live_...", room: "my-room" }}>
<Counter />
</YSDKProvider>
)
}
function Counter() {
const [count, setCount] = useShared('count', 0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
Open two tabs. Click the button. Both tabs update.
Everything you need
useShared
Shared state that works like useState. Numbers, strings, objects — any JSON value, synced across all clients.
const [name, setName] = useShared('name', 'Andy')
useSharedArray
Shared arrays with CRDT merge semantics. Concurrent insertions from different users merge cleanly — no conflicts.
const [todos, ops] = useSharedArray('todos')
useSharedText
Character-by-character collaborative text editing. Compatible with CodeMirror, ProseMirror, Tiptap, and Monaco.
const { value, ytext } = useSharedText('doc')
usePresence
See who's connected and share ephemeral state like cursors, selections, and typing indicators.
const { peers, setPresence } = usePresence({ cursor })
useBroadcast
Fire-and-forget messages to all connected clients. Reactions, notifications, sound effects — anything ephemeral.
const { broadcast, onMessage } = useBroadcast('fx')
useYSDK
Escape hatch to the raw Yjs document. Full CRDT API access when you need fine-grained control.
const { doc, awareness } = useYSDK()
Self-host or Cloud
Self-hosted
Works with any y-websocket server. Run npx y-websocket or deploy Hocuspocus for production.
<YSDKProvider
url="ws://localhost:1234"
room="my-room"
>
YSDK Cloud
Zero setup. Get an API key, add the cloud prop, and you're live. Global edge infrastructure.
<YSDKProvider
cloud={{
apiKey: "ysdk_live_...",
room: "my-room"
}}
>
Get started in 30 seconds
Install
npm install @ysdk/react
Start a server
npx y-websocket
Add the provider
<YSDKProvider url="ws://localhost:1234" room="my-room">
Use hooks
const [count, setCount] = useShared('count', 0)