Embed collaborative experiences into your React app

Liveblocks empowers developers to embed performant collaborative features to any product in just days.

Companies of all sizes and industries use Liveblocks

Presence

Show who’s in a document

Add presence features to your product to make people feel like they’re together in the same room.

import {  useOthers,  useUpdateMyPresence} from "./liveblocks.config";
// Pass this to RoomProviderconst initialPresence = { cursor: { x: 0, y: 0 } };
export default function Presence() { const updateMyPresence = useUpdateMyPresence(); const others = useOthers();
return ( <div onPointerMove={(event) => { updateMyPresence({ cursor: { x: event.clientX, y: event.clientY, }, }) }} > {others.map(({ connectionId, presence }) => { return ( <Cursor key={connectionId} cursor={presence.cursor} /> ) })} </div> )}

Broadcast

Broadcast events in real‑time

Use broadcast events to notify in real‑time other connected clients to the room.

import { useState } from "react";import {  useBroadcastEvent,  useEventListener,} from "./liveblocks.config";
export default function Broadcast() { const [count, setCount] = useState(0); const broadcast = useBroadcastEvent();
useEventListener(({ connectionId, event }) => { switch (event.type) { case "increase": setCount((count) => count + 1); break; case "decrease": setCount((count) => count === 0 ? 0 : count - 1); break; } });
return ( <> {count} <button onClick={() => broadcast({ type: "decrease" })}> - </button> <button onClick={() => broadcast({ type: "increase" })}> + </button> </> )}

Storage

Shared real‑time document state

Use conflict‑free data types to enable people to edit the same document in real‑time.

import { LiveObject } from "@liveblocks/client";import { useStorage, useMutation } from "./liveblocks.config";
// Pass these to RoomProviderconst initialStorage = { scientist: new LiveObject({ firstName: "Ada", lastName: "Lovelace", }),};
export default function Form() { const scientist = useStorage(root => root.scientist);
const update = useMutation(({ storage }, field, value) => { storage.get('scientist').set(field, value); }, []);
return ( <> <input value={scientist.firstName} onChange={(e) => { update("firstName", e.target.value) } /> <input value={scientist.lastName} onChange={(e) => { update("lastName", e.target.value) } /> </> );}

Start making your product collaborative with the Liveblocks toolkit today