Skip to main content

Adding Real-Time Collaboration to Custom Web Apps Without the Complexity

How to build multiplayer features like live cursors, co-editing, and real-time updates into your web apps using modern tools and pragmatic architecture.

Your users now expect multiplayer. Google Docs trained an entire generation to assume that if two people are looking at the same screen, they should see each other's changes instantly. In 2026, that expectation has bled into every custom tool, client portal, and internal dashboard we build. The good news: you no longer need a PhD in distributed systems to ship real-time features.

Why Real-Time Matters Beyond Chat

When most teams hear "real-time," they think chat or notifications. But the highest-impact real-time features are often quieter: a sales team seeing pipeline updates without refreshing, two operations managers editing the same inventory sheet simultaneously, or a client portal where both sides watch a project status change live.

We've built real-time collaboration into custom tools for clients across Lagos, Kingston, and Toronto. The pattern is consistent: teams that see each other's work in real time make fewer duplicate decisions and resolve conflicts faster. One logistics client in Nigeria cut order processing errors by 35% simply by adding live presence indicators to their dispatch dashboard—dispatchers could see who was already handling which order.

The Modern Real-Time Stack

Five years ago, building real-time meant wrestling with raw WebSockets, writing your own reconnection logic, and managing state synchronization from scratch. Today, the tooling has matured dramatically. Here's what actually works in production:

1. Supabase Realtime for Database-Driven Updates

If your app already runs on Supabase (or PostgreSQL), Supabase Realtime is the lowest-friction option. It listens to Postgres changes via logical replication and broadcasts them over WebSockets. You subscribe to table changes in a few lines of code:

  • Best for: Dashboards, admin panels, status boards—anything where the source of truth is a database row
  • Latency: Typically 50-150ms from write to client update
  • Limitation: Not ideal for high-frequency updates like live cursors (use Supabase's Broadcast channel for that)

2. Liveblocks for Document-Style Collaboration

Liveblocks handles the hard parts of multiplayer: conflict resolution, presence awareness, and offline support. It provides CRDTs (Conflict-free Replicated Data Types) out of the box, which means two users editing the same field simultaneously won't overwrite each other's work.

  • Best for: Co-editing interfaces, collaborative forms, design tools, whiteboard features
  • Pricing: Free tier covers up to 300 monthly active users—enough for most internal tools
  • Integration: First-class React hooks, works seamlessly with Next.js

3. PartyKit / Cloudflare Durable Objects for Custom Logic

When you need real-time and server-side logic—like validating moves in a workflow, rate-limiting updates, or aggregating data before broadcasting—PartyKit (now part of the Cloudflare ecosystem) gives you programmable WebSocket rooms running at the edge. Each "party" is a stateful server that can hold data in memory and persist to storage.

  • Best for: Complex collaborative workflows, real-time auctions, live dashboards with computed aggregations
  • Edge deployment: Rooms spin up close to your users—critical for teams split between Lagos and London

Architecture Decisions That Save You Pain

Choosing a tool is the easy part. The architecture around it determines whether your real-time features stay reliable at scale or become a debugging nightmare.

Separate Your Real-Time Layer From Your API Layer

Don't route real-time updates through the same API endpoints that handle CRUD operations. Keep your REST or tRPC API as the source of truth for writes, and let your real-time layer handle reads and subscriptions. This means a failed WebSocket connection never blocks a user from saving their work.

Design for Reconnection From Day One

Mobile networks in Lagos drop. WiFi in Kingston fluctuates. Your real-time layer will disconnect. Every implementation needs three things:

  • Exponential backoff reconnection—don't hammer your server with retry attempts
  • State reconciliation on reconnect—fetch the latest state via your API, then resubscribe to the real-time stream
  • Optimistic UI with rollback—show the user's action immediately, correct it if the server disagrees after reconnection

Use Presence Deliberately

Presence indicators (showing who's online, where their cursor is, what they're editing) are cheap to implement but expensive if overused. Broadcasting cursor positions 60 times per second across 50 users creates real load. Throttle presence updates to 5-10Hz for cursors, and use simple "viewing this page" indicators for most internal tools. Save fine-grained presence for features where it genuinely prevents conflicts.

What This Looks Like in a Next.js App

For a typical internal tool built with Next.js 15 and the App Router, our go-to architecture looks like this:

  • Data mutations: Server Actions or tRPC mutations write to PostgreSQL
  • Real-time subscriptions: Supabase Realtime (for database change streams) or Liveblocks (for collaborative editing)
  • Presence: Liveblocks useOthers() hook for lightweight "who's here" indicators
  • Fallback: SWR or React Query polling at 5-second intervals when WebSocket connections fail

This hybrid approach means the app always works—real-time enhances the experience but isn't a single point of failure. Progressive enhancement applied to multiplayer.

When Real-Time Isn't Worth the Complexity

Not every app needs live updates. If your users typically work solo, if data changes infrequently (less than once per minute), or if your team doesn't have the bandwidth to test edge cases around reconnection and conflict resolution—a simple "Refresh" button or 30-second polling interval is a perfectly valid choice.

We've talked clients out of real-time features as often as we've built them. The question isn't "can we?" but "does this solve a real coordination problem?"

Start With Presence, Then Layer Up

If you're adding real-time to an existing app, start with the simplest high-value feature: showing who else is looking at the same record. It takes an afternoon to implement with Liveblocks or Supabase Broadcast, immediately reduces "did you already handle this?" Slack messages, and gives your team a foundation to build more sophisticated collaboration features when the use case is clear.

Real-time collaboration used to be a feature reserved for companies with dedicated infrastructure teams. In 2026, the tools have caught up to the expectation. The challenge now is choosing the right level of real-time for each feature—and building it so it degrades gracefully when the network doesn't cooperate.

Back to Blog