npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bgio-partykit

v0.1.0

Published

boardgame.io on PartyKit with Socket.IO

Readme

bgio-partykit

Deploy boardgame.io multiplayer games to Cloudflare Workers using PartyKit — with zero client-side changes.

bgio-partykit is a library and CLI that lets you run boardgame.io game servers on PartyKit's Durable Objects infrastructure. Your existing Client with SocketIO() transport and LobbyClient work exactly as they do today — no UI or networking code needs to change.


✨ Key Features

  • Zero client-side changes — Use the standard boardgame.io Client with SocketIO() transport. Existing games and frontends work out of the box.
  • Standard LobbyClient compatibility — The full boardgame.io lobby REST API (/games, /games/:name/create, /games/:name/:id/join, etc.) is implemented and served from PartyKit.
  • Match persistence via PartyKit room.storage — Every match is a Durable Object with its own StorageAPI.Async backend. Game state, metadata, and logs survive restarts and are replicated across Cloudflare's edge.
  • Deploy to Cloudflare Workers via PartyKit — One-command deploy to Cloudflare's global edge network. No server management, no Docker, no scaling headaches.
  • Interactive CLI scaffoldingpnpm create bgio-partykit scaffolds a complete, working project with your game definition, TypeScript configs, and PartyKit manifest in seconds.
  • TypeScript-first — Full type definitions for the public API, game registry, storage layer, and transport adapters.

🚀 Quick Start

The fastest way to get started is with the interactive CLI:

pnpm create bgio-partykit my-game
cd my-game
pnpm dev        # starts the local PartyKit dev server on localhost:1999

The CLI will ask you for a project name, game name, and number of players. It then:

  1. Copies bundled templates with your variables substituted.
  2. Runs pnpm install.
  3. Runs git init.
  4. Prints next steps.

Open the generated demo page or point your existing boardgame.io client at http://localhost:1999 and it will just work.


🔧 Manual Setup (for Existing Projects)

If you already have a boardgame.io game and want to host it on PartyKit:

1. Install the package

npm install bgio-partykit

2. Create a server entrypoint

Create a file (e.g., src/server.ts) that exports the default Server class and registers your games:

import Server, { registerGame } from "bgio-partykit";
import MyGame from "./game";

// Register your game(s)
registerGame(MyGame);

// Export the Server as the PartyKit room entrypoint
export default Server;

3. Configure partykit.json

Create a partykit.json at the project root:

{
  "name": "my-bgio-game",
  "main": "src/server.ts",
  "serve": {
    "path": "static"
  },
  "compatibilityDate": "2024-07-01",
  "parties": {
    "lobby": "src/server.ts",
    "match": "src/server.ts",
    "bus": "src/server.ts"
  }
}

All three party kinds (lobby, match, bus) point to the same server file. The runtime routes requests to the appropriate internal handler based on the room name.

4. Wire up your client

Your existing client code requires only the server URL:

import { Client } from "boardgame.io/react";
import { SocketIO } from "boardgame.io/multiplayer";
import { LobbyClient } from "boardgame.io/client";
import MyGame from "./game";
import { socketIOServerUrl, lobbyClientUrl } from "bgio-partykit";

const BASE_URL = "http://localhost:1999";   // or your deployed URL

const App = Client({
  game: MyGame,
  transport: SocketIO({ server: socketIOServerUrl(BASE_URL) }),
});

const lobby = new LobbyClient({ server: lobbyClientUrl(BASE_URL) });

🏗 Architecture Overview

┌─────────────────┐     WebSocket      ┌─────────────────────────────┐
│  boardgame.io   │ ◄─────────────────►│   PartyKit Durable Object   │
│  Client +       │   Socket.IO        │   (one per match room)      │
│  LobbyClient    │                    │                             │
└─────────────────┘                    │  ┌───────────────────────┐  │
                                       │  │  vendored party.io    │  │
                                       │  │  Socket.IO server     │  │
                                       │  └───────────────────────┘  │
                                       │            │                │
                                       │  ┌───────────────────────┐  │
                                       │  │  boardgame.io Master  │  │
                                       │  │  (authoritative logic)│  │
                                       │  └───────────────────────┘  │
                                       │            │                │
                                       │  ┌───────────────────────┐  │
                                       │  │  StorageAPI.Async     │  │
                                       │  │  backed by            │  │
                                       │  │  room.storage         │  │
                                       │  └───────────────────────┘  │
                                       └─────────────────────────────┘
  • Each match is a PartyKit room — A Cloudflare Durable Object that maintains WebSocket connections, game state, and in-memory queues for that specific match.
  • Socket.IO server via vendored party.io — The project bundles a fork of party.io that implements a Socket.IO server on top of PartyKit's WebSocket infrastructure, enabling SocketIO() transport compatibility.
  • Authoritative Master class — The standard boardgame.io Master processes all moves server-side. Game rules, turn order, and state transitions run inside the Durable Object exactly as they would on a Node.js server.
  • StorageAPI.Async backed by room.storage — Match state, metadata, logs, and initial state are persisted to PartyKit's transactional key-value storage. The PartyKitStorage class implements the full StorageAPI contract.
  • TransportAPI adapter with playerView filteringcreateTransportAPI builds a boardgame.io-compatible transport layer that broadcasts updates to all connected sockets, applying per-player playerView filtering so clients only see the state they are allowed to see.

📚 API Reference

Server (default export)

The PartyKit room entrypoint. Implements Party.Server and handles HTTP requests, WebSocket upgrades, lobby routing, and Socket.IO handshakes.

import Server from "bgio-partykit";
export default Server;

Game Registry

import { registerGame, getGame, listGames, getGames } from "bgio-partykit";
import type { RegisteredGame } from "bgio-partykit";

registerGame(myGame);
const names = listGames();          // ["tic-tac-toe", "my-game"]
const game = getGame("my-game");    // RegisteredGame | undefined

Storage API

import {
  PartyKitStorage,
  StorageType,
  RemoteStorage,
} from "bgio-partykit";
import type {
  FetchOpts,
  CreateMatchOpts,
  ListMatchesOpts,
} from "bgio-partykit";
  • PartyKitStorage — Direct StorageAPI implementation backed by a Party.Storage instance. Used inside the match Durable Object.
  • RemoteStorage — Async StorageAPI implementation that forwards CRUD operations to the match Durable Object via HTTP. Used by the lobby Durable Object.
  • StorageType.SYNC / StorageType.ASYNC — Storage type constants.

Transport API

import { createTransportAPI } from "bgio-partykit";

Builds a boardgame.io TransportAPI for a given socket, game definition, and match ID. Handles per-player state filtering and broadcast/fallback logic for PartyKit's I/O isolation.

URL Helpers

import { lobbyClientUrl, socketIOServerUrl } from "bgio-partykit";

const lobby = new LobbyClient({ server: lobbyClientUrl("http://localhost:1999") });
const client = Client({
  game: TicTacToe,
  transport: SocketIO({ server: socketIOServerUrl("http://localhost:1999") }),
});

Demo Game

import { TicTacToe } from "bgio-partykit";
import type { TicTacToeState } from "bgio-partykit";

A built-in Tic-Tac-Toe game definition, useful for testing and as a reference implementation.


🌐 Deploying

Deploy your game to Cloudflare Workers with a single command:

pnpm deploy

Before deploying, make sure the following environment variables are set:

export CLOUDFLARE_ACCOUNT_ID=your-account-id
export CLOUDFLARE_API_TOKEN=your-api-token

You can find these in your Cloudflare dashboard. The deploy script builds the project and pushes it to PartyKit's edge infrastructure, making your game server available globally within seconds.


🧪 Testing

The repository includes unit tests, local end-to-end tests, and deployed end-to-end tests.

| Command | Description | |---------|-------------| | pnpm test | Run unit tests with Vitest | | pnpm dev | Start local PartyKit dev server on localhost:1999 | | pnpm e2e:local | Run E2E suite against the local dev server | | pnpm e2e:deployed | Run E2E suite against the currently deployed instance | | pnpm e2e:lobby-client | Verify LobbyClient compatibility | | pnpm lint | ESLint | | pnpm typecheck | TypeScript --noEmit |

E2E Tests

E2E scripts spin up the dev server, create matches via the lobby API, connect Socket.IO clients, play moves, assert state transitions, and clean up. They exercise the full stack: lobby → match DO → storage → transport → Socket.IO broadcast.


📁 Project Structure

bgio-partykit/
├── src/
│   ├── index.ts              # Public API exports
│   ├── server.ts             # PartyKit Server entrypoint (lobby / match / bus routing)
│   ├── match-room.ts         # Per-match Durable Object logic (Master, queues, sockets)
│   ├── lobby.ts              # Lobby REST API handlers (create, join, leave, play again)
│   ├── registry.ts           # Game registry (registerGame, getGame, listGames)
│   ├── storage.ts            # PartyKitStorage (StorageAPI.Async via room.storage)
│   ├── remote-storage.ts     # RemoteStorage (HTTP-forwarding StorageAPI for lobby)
│   ├── transport.ts          # createTransportAPI with playerView filtering
│   └── games/
│       └── tic-tac-toe.ts    # Built-in demo game
├── packages/
│   ├── party.io/             # Vendored Socket.IO server for PartyKit
│   └── create-bgio-partykit/ # Interactive CLI scaffolding package
├── scripts/
│   ├── e2e-local.mjs         # Local E2E test runner
│   ├── e2e-deployed.mjs      # Deployed E2E test runner
│   └── deploy.mjs            # Deploy helper script
├── static/
│   └── index.html            # Static demo page served by PartyKit
├── tests/
│   ├── e2e/                  # End-to-end test suites
│   ├── foundation/             # Unit tests for core utilities
│   ├── lobby/                  # Lobby API unit tests
│   └── runtime/                # Runtime / integration tests
├── partykit.json             # PartyKit manifest (parties, compat date, serve)
├── package.json              # Package manifest & scripts
└── README.md                 # You are here

📄 License

MIT