Everything you need for real-time collaboration

Ship presence, cursors, document sync, and custom events with a few lines of code. Production-ready from day one.

Live Presence

See who is online in real-time with custom metadata. Show avatars, names, status indicators, and any user-defined data across all connected clients.

import { usePresence } from '@realtime-sdk/react';

function OnlineUsers() {
  const { others, updatePresence } = usePresence('room-1');

  // Set your presence data
  updatePresence({ name: 'Alice', status: 'active' });

  return (
    <div className="flex gap-2">
      {others.map(user => (
        <Avatar key={user.id} name={user.name} />
      ))}
    </div>
  );
}

Cursor Tracking

Display live cursor positions with smooth interpolation and automatic color coding. Built-in support for pointer events with zero-config setup.

import { useCursors } from '@realtime-sdk/react';

function Canvas() {
  const { cursors, onPointerMove } = useCursors('room-1');

  return (
    <div onPointerMove={onPointerMove}>
      {cursors.map(cursor => (
        <Cursor
          key={cursor.id}
          x={cursor.x}
          y={cursor.y}
          color={cursor.color}
          label={cursor.name}
        />
      ))}
    </div>
  );
}

Document Sync

Conflict-free collaborative editing powered by Yjs CRDTs. Works with any text editor, rich-text framework, or custom data structures.

import { useYDoc } from '@realtime-sdk/react';
import * as Y from 'yjs';

function Editor() {
  const { doc, provider } = useYDoc('room-1', 'document');

  // Bind to any Yjs-compatible editor
  const text = doc.getText('content');

  // Changes sync automatically
  text.insert(0, 'Hello, collaborators!');

  return <RichTextEditor doc={doc} provider={provider} />;
}

Custom Events

Broadcast arbitrary events to room members. Build reactions, notifications, live polls, and any real-time interaction pattern you need.

import {
  useBroadcast,
  useEventListener,
} from '@realtime-sdk/react';

function Reactions() {
  const broadcast = useBroadcast('room-1');

  // Send events to all room members
  const sendReaction = (emoji: string) => {
    broadcast('reaction', { emoji, timestamp: Date.now() });
  };

  // Listen for incoming events
  useEventListener('room-1', 'reaction', (data) => {
    showReactionAnimation(data.emoji);
  });

  return <EmojiPicker onSelect={sendReaction} />;
}

Auto Reconnect

Exponential backoff with automatic state recovery. Handle network issues, tab suspension, and connection drops gracefully without user intervention.

import { RealtimeClient } from '@realtime-sdk/client';

const client = new RealtimeClient({
  url: 'wss://api.yourapp.com/ws',
  token: authToken,
  reconnect: {
    enabled: true,
    maxRetries: 10,
    backoff: 'exponential',
    maxDelay: 30000,
  },
});

client.on('reconnected', () => {
  console.log('Back online — state recovered');
});

Secure by Default

JWT authentication, room-level access control, and encrypted WebSocket connections. Fine-grained permissions let you control who can read, write, or broadcast in each room.

import { RealtimeClient } from '@realtime-sdk/client';

// Server-side: generate a scoped JWT
const token = jwt.sign({
  sub: user.id,
  rooms: {
    'project-123': ['read', 'write'],
    'announcements': ['read'],
  },
}, process.env.REALTIME_SECRET);

// Client-side: connect with the token
const client = new RealtimeClient({
  url: 'wss://api.yourapp.com/ws',
  token,
});

Ready to add real-time features?

Start with Free, then upgrade through Stripe Checkout in minutes. Keep your pace with commercial-grade support when you scale.