Real-time multiplayer presence and live cursors for any web app — in 10 lines of code.
Bundle sizes: @xevrion/flock-core ~6KB gzipped · @xevrion/flock-react ~3KB gzipped
npm install @xevrion/flock-react
npx @xevrion/flock-serverimport { FlockProvider, useCursors, usePresence } 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",
color: cursor.metadata.color,
}}
>
{cursor.metadata.name}
</div>
))}
</>
);
}
export default function App() {
return (
<FlockProvider
serverUrl="ws://localhost:8787"
roomId="my-room"
userId="user-123"
metadata={{ name: "Alice", color: "#7c5cff" }}
>
<CursorOverlay />
</FlockProvider>
);
}Open the page in two browser tabs and move your mouse — each tab sees the other's cursor.
| Flock | Liveblocks | DIY | |
|---|---|---|---|
| Self-hostable | Yes | No | Yes |
| License | MIT | Partial AGPL | — |
| Per-seat pricing | None | Yes (free tier has hard caps) | None |
| Connection caps | None | 10 per room on free tier | None |
| Setup time | 10 lines | Full platform onboarding | Weeks |
| Bundle size | ~6KB gzipped | Much larger | — |
Flock does one thing well: presence and live cursors. If you need document sync, comments, or notifications — those are out of scope by design. Flock is the smallest thing that makes your app feel multiplayer.
- Canvas demo — collaborative canvas with live cursors and presence bar
- Presence widget — "who's viewing this page" widget
Open the canvas demo in two browser tabs and share the ?room= URL to see cursors in real time. Both demos run locally too with pnpm --filter demo-canvas dev and pnpm --filter demo-presence dev after starting the server.
# Docker (recommended for production)
docker run -p 8787:8787 \
-e FLOCK_REDIS_URL=redis://your-redis:6379 \
ghcr.io/xevrion/flock-server:latest# npx (quickest for local dev)
npx @xevrion/flock-server# Programmatic (embed in an existing Node server)
import { FlockServer } from "@xevrion/flock-server";
const server = new FlockServer({ port: 8787, redisUrl: process.env.REDIS_URL });
await server.start();| Variable | Default | Description |
|---|---|---|
FLOCK_PORT |
8787 |
Port to listen on |
FLOCK_REDIS_URL |
— | Redis URL; enables TTL eviction and pub/sub fan-out for multi-instance |
FLOCK_API_KEYS |
— | Comma-separated API keys; omit for open mode |
FLOCK_PRESENCE_TTL_SECONDS |
30 |
Seconds before an idle user is evicted |
FLOCK_MAX_MESSAGES_PER_SECOND |
100 |
Per-connection rate limit |
FLOCK_MAX_ROOM_SIZE |
10 |
Max users per room; 11th person is rejected |
FLOCK_ADMIN_PASSWORD |
— | Enables /admin dashboard when set |
FLOCK_LOG_LEVEL |
info |
Pino log level |
| Package | Description |
|---|---|
@xevrion/flock-core |
Framework-agnostic WebSocket transport, cursor throttling and interpolation, reconnection with exponential backoff |
@xevrion/flock-react |
React hooks: usePresence, useCursors, useMyPresence, useConnectionStatus, useRoom |
@xevrion/flock-server |
Node.js WebSocket server with Redis-backed presence TTL and pub/sub fan-out |
pnpm install
pnpm build
node packages/server/dist/cli.js # server on :8787
pnpm --filter demo-canvas dev # canvas demo on :3100Open http://localhost:3100 in two tabs and share the ?room= URL.
With Redis, multiple server instances coordinate via pub/sub. Clients on different instances see each other's cursors:
FLOCK_PORT=8787 FLOCK_REDIS_URL=redis://localhost:6379 node packages/server/dist/cli.js &
FLOCK_PORT=8788 FLOCK_REDIS_URL=redis://localhost:6379 node packages/server/dist/cli.js &pnpm test58 tests across core, react, and server packages covering: cursor throttling and interpolation, reconnection with backoff, presence TTL eviction, duplicate-join handling, cursor buffering, API key auth, rate limiting, and cross-instance pub/sub relay.
Full documentation at flock.xevrion.dev (or flock-docs.vercel.app). Run locally:
pnpm --filter docs devOpen http://localhost:3200.
See CONTRIBUTING.md. Issues and pull requests are welcome.
MIT — Yash Bavadiya (@xevrion)