Flock
Getting started

Quickstart

Add live cursors to your React app in under 5 minutes.

1. Start the server

The Flock server handles all the WebSocket connections. Run it locally with npx (no install needed):

npx @xevrion/flock-server

Or with Docker:

docker run -p 8787:8787 ghcr.io/xevrion/flock-server:latest

The server starts on port 8787 by default. You should see:

flock server starting
  port:      8787
  redis:     none (single-instance mode)

2. Install the React package

npm install @xevrion/flock-react

3. Add cursors to your app

Wrap your app (or just the page that needs cursors) in <FlockProvider>, then call useCursors() to render other users' cursor positions:

import { FlockProvider, useCursors } from "@xevrion/flock-react";
 
function CursorOverlay() {
  const cursors = useCursors();
  return (
    <>
      {Object.values(cursors).map((cursor) => (
        <div
          key={cursor.userId}
          style={{
            position: "fixed",
            left: `${cursor.position.x * 100}%`,
            top: `${cursor.position.y * 100}%`,
            pointerEvents: "none",
          }}
        >
          {cursor.metadata.name}
        </div>
      ))}
    </>
  );
}
 
export default function App() {
  return (
    <FlockProvider
      serverUrl="ws://localhost:8787"
      roomId="my-room"
      userId="user-123"
      metadata={{ name: "Alice" }}
    >
      <CursorOverlay />
      {/* rest of your app */}
    </FlockProvider>
  );
}

Open this page in two browser tabs and move your mouse — you'll see each tab's cursor in the other.

4. Track mouse movement

By default, Flock tracks the mouse relative to the viewport and normalizes positions to 0–1 so cursors line up across different screen sizes. No extra code needed — the provider handles it.

To track within a specific element (like a canvas):

import { useRoom } from "@xevrion/flock-react";
import { useEffect, useRef } from "react";
 
function Canvas() {
  const room = useRoom();
  const ref = useRef<HTMLDivElement>(null);
 
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e: MouseEvent) => {
      const rect = el.getBoundingClientRect();
      room.updateCursor({
        x: (e.clientX - rect.left) / rect.width,
        y: (e.clientY - rect.top) / rect.height,
      });
    };
    el.addEventListener("mousemove", onMove);
    return () => el.removeEventListener("mousemove", onMove);
  }, [room]);
 
  return <div ref={ref} style={{ width: "100%", height: "100%" }} />;
}

Try it live

Open this page in two browser tabs and move your mouse in the area below:

If the demo shows "Server not available", start the server locally first (npx @xevrion/flock-server) and set NEXT_PUBLIC_FLOCK_SERVER_URL=ws://localhost:8787 in apps/docs/.env.local.

Next steps

On this page