DEV Community

Alex Spinov
Alex Spinov

Posted on

PartyKit Has a Free API That Adds Multiplayer to Any App in 10 Lines

PartyKit is the simplest way to build real-time, multiplayer, collaborative features. Rooms, WebSockets, state sync — deployed to Cloudflare's edge in one command.

What Is PartyKit?

PartyKit gives you programmable rooms with WebSocket support. Each room runs your server-side code and syncs state to all connected clients. Think Firebase Realtime Database, but you control the logic.

Quick Start

npx create-partykit-app my-app
cd my-app && npx partykit dev
Enter fullscreen mode Exit fullscreen mode

Server: Define a Room

// party/index.ts
import type { Party, Connection } from 'partykit/server'

export default class ChatRoom implements Party.Server {
  messages: { user: string; text: string; ts: number }[] = []

  onConnect(conn: Connection) {
    // Send history to new user
    conn.send(JSON.stringify({ type: 'history', messages: this.messages }))
  }

  onMessage(message: string, sender: Connection) {
    const data = JSON.parse(message)
    const msg = { user: data.user, text: data.text, ts: Date.now() }
    this.messages.push(msg)

    // Broadcast to all connected users
    this.room.broadcast(JSON.stringify({ type: 'message', ...msg }))
  }
}
Enter fullscreen mode Exit fullscreen mode

Client: Connect to Room

import PartySocket from 'partysocket'

const socket = new PartySocket({
  host: 'my-app.username.partykit.dev',
  room: 'chat-room-1',
})

socket.addEventListener('message', (event) => {
  const data = JSON.parse(event.data)
  if (data.type === 'message') {
    console.log(`${data.user}: ${data.text}`)
  }
})

// Send message
socket.send(JSON.stringify({ user: 'Alice', text: 'Hello!' }))
Enter fullscreen mode Exit fullscreen mode

React Hook

import usePartySocket from 'partysocket/react'

function ChatRoom({ roomId }: { roomId: string }) {
  const [messages, setMessages] = useState([])

  const socket = usePartySocket({
    host: 'my-app.username.partykit.dev',
    room: roomId,
    onMessage(event) {
      const data = JSON.parse(event.data)
      if (data.type === 'message') {
        setMessages(prev => [...prev, data])
      }
    },
  })

  const send = (text: string) => {
    socket.send(JSON.stringify({ user: currentUser, text }))
  }

  return (
    <div>
      {messages.map(m => <p key={m.ts}><b>{m.user}:</b> {m.text}</p>)}
      <input onKeyDown={e => e.key === 'Enter' && send(e.target.value)} />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Use Cases

  • Collaborative editing: shared cursors, conflict resolution
  • Live chat: per-page, per-document, per-game rooms
  • Multiplayer games: turn-based, real-time state sync
  • Live polls and voting: instant results
  • Presence: show who is online, typing indicators
  • IoT dashboards: real-time device telemetry

HTTP API (Room as REST endpoint)

// party/index.ts
export default class ApiRoom implements Party.Server {
  data: Record<string, any> = {}

  async onRequest(request: Party.Request) {
    if (request.method === 'GET') {
      return new Response(JSON.stringify(this.data))
    }
    if (request.method === 'POST') {
      this.data = await request.json()
      this.room.broadcast(JSON.stringify(this.data))
      return new Response('OK')
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Deploy

npx partykit deploy
# Deployed to: my-app.username.partykit.dev
Enter fullscreen mode Exit fullscreen mode

Free Tier

Feature Free Pro
Connections 20 concurrent 100K
Rooms Unlimited Unlimited
Requests 100K/day Unlimited
Edge locations All All

Need real-time data from the web? Scrapfly + PartyKit = live web data sync. Email spinov001@gmail.com for real-time scraping solutions.

Top comments (0)