00:00 / 00:00

LAPLACE Chat

LAPLACE Event Bridge

Monorepo Structure

This repository contains multiple packages:

  • Server (Go) (packages/server): Standalone Go implementation of the WebSocket bridge (recommended)
  • Server (Bun, deprecated) (packages/server-bun): Original Bun/Node.js implementation kept for reference
  • SDK (packages/sdk): TypeScript/JavaScript client for connecting to the bridge
  • Examples (examples/): Usage examples for the SDK

Features

  • Role-based connection system (server/client)
  • Server-to-clients message broadcasting
  • SDK support for receiving as a client or publishing as the server role
  • Token-based authentication
  • Reconnection support

Requirements

  • Bun v1.2.0 or higher (required for managing the monorepo and running the SDK / Bun server)
  • Go 1.23.0 or higher (only for building or running the Go server from source; the project selects the Go 1.24.2 toolchain)

Installation

You can run the server in different methods:

  • Pre-compiled binaries (easiest for non-technical users)
  • Go server (easy to deploy, recommended)
  • laplace-event-fetcher bridge mode (recommended for stability)
  • Bun server (deprecated, only for reference)
  • Source code (for advanced users and developers)

Pre-compiled Binaries

If you're not familiar with programming or command-line tools, the easiest way to run the LAPLACE Event Bridge server is to download a pre-compiled binary from our GitHub releases:

  1. Download the server

    • Go to the GitHub Releases page
    • Find the latest release with @laplace.live/event-bridge-server in the name
    • Download the appropriate file for your operating system:
      • Windows: leb-server-windows-x64.exe
      • macOS: leb-server-darwin-arm64
      • Linux (x64): leb-server-linux-x64
      • Linux (arm64): leb-server-linux-arm64
  2. Make it executable (macOS/Linux only):

    • Open Terminal
    • Navigate to your Downloads folder: cd ~/Downloads
    • Run: chmod +x leb-server-* (replace * with your actual filename)
  3. Run the server:

    • Windows: Double-click the .exe file
    • macOS: In Terminal, run ./leb-server-darwin-arm64
    • Linux: In Terminal, run ./leb-server-linux-x64 (replace x64 with arm64 when needed)

The server will start and display a message when it's ready to accept connections.

Bridge Server (Go)

The recommended bridge server is now a single-binary Go application located in packages/server. Building or running it does not require Bun – only the Go tool-chain.

For full documentation see packages/server/README.md, but a quick start looks like this:

# Enter the Go module and run from source
cd packages/server
go run . --debug

# Or build a native binary
go build -o leb-server .
./leb-server --host 0.0.0.0 --auth "your-secure-token"

The server listens on http://localhost:9696 by default.

Event Fetcher Bridge Mode

In the latest version of laplace-event-fetcher (v2.2.0 and above), you can enable the WebSocket bridge mode to run the event fetcher as a bridge server for better stability. With this mode, you do not need to keep the LAPLACE Chat dashboard running as it will run as the event fetcher + bridge server for you.

Bridge Server (Bun, Deprecated)

The original Bun/Node.js implementation lives in packages/server-bun. It is feature-equivalent but has been superseded by the Go version for performance and deployment simplicity. It is still shipped for anyone relying on it.

# Start the Bun server
bun run --cwd packages/server-bun start --debug --auth "your-secure-token"

Server Comparison

FeatureBridge Server (Go)Event Fetcher Bridge Mode
InstallationSingle binary or Go toolchainRequires LAPLACE Event Fetcher v2.2.0+
EnvironmentLocal (standalone binary)Container
DeploymentEasy - single file deploymentNeeds server running
Event SourceLAPLACE Chat console or SDK server roleBuilt into Event Fetcher
Reuse Local ConnectionYesNo
ConfigurationCommand-line flagsEvent fetcher config
StabilityDepends on your local networkBetter stability
Best ForHobby projects integration, small scaleProduction ready and large scale for MCN agencies, or users already using event fetcher

LLM Prompt

Paste the prompt below into your AI assistant, or keep it in a rules file such as CLAUDE.md or AGENTS.md, and it has the background it needs to write integrations for you. The documentation URLs it cites are all fetchable

You are helping me build an integration on top of LAPLACE Event Bridge, the WebSocket
bridge that relays real-time Bilibili live events — chat messages, gifts, super chats,
guard purchases, stream state — from LAPLACE Chat (https://chat.laplace.live) to local
clients.

Before writing any code, fetch the reference documents listed at the end — they are
the single source of truth for event types, payload fields and the client API. Do
not rely on memory and do not invent names.

## Setup

- Install `@laplace.live/event-bridge-sdk`. It runs anywhere with `WebSocket` and
  `fetch` globals: Node.js 22+, Bun and browsers. Event payload interfaces live in
  its dependency `@laplace.live/event-types`.
- A bridge server must be running: either the `leb-server` binary fed by LAPLACE Chat
  or an SDK v1.2.0+ producer using `role: 'server'`, or LAPLACE Event Fetcher v2.2.0+
  in bridge mode (standalone). Default endpoint: `ws://localhost:9696`.
- Auth is optional: when the server was started with `--auth`, pass the same string
  as `token`.

## Client

```ts
import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const bridge = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696", // default
  token: "your-auth-token", // only when the server enables auth
});

bridge.on("message", (event) => {
  console.log(`${event.username}: ${event.message}`); // typed as Message
});
const offAny = bridge.onAny((event) => console.log(event.type, event.origin));

await bridge.connect();
// later: offAny(); bridge.disconnect();
```

## Producer (Server Role)

SDK v1.2.0+ can instead occupy the event-producing server role. This connects to
a running standalone Event Bridge server; it does not start the bridge server itself.

```ts
const producer = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token",
  role: "server",
});

await producer.connect();
producer.send(event); // event must be a LaplaceEvent
```

Only server-role messages are broadcast. A client-role `send()` is acknowledged by
the bridge but is not relayed to other connections.

The bridge is one-way — servers broadcast, clients listen — and reconnection is
automatic. Handlers are typed from the event name. Every event carries `type`, `id`
and `origin` (the canonical room id — filter on it when one bridge serves several
rooms). The exact event names, payload fields and the rest of the client API live in
the reference below — look them up instead of guessing.

## Reference

Fetch these before writing code:

- https://laplace.live/chat/event-bridge.en.mdx — this page as raw Markdown: server
  setup, SDK client and producer roles, connection state, room discovery
- https://chat.laplace.live/event-types/ — every event type and payload field
- https://github.com/laplace-live/event-bridge — server and SDK source with runnable
  examples

SDK

The SDK provides a type-safe connection to the event bridge. It can receive events as a client or produce them as the server role.

Installation

npm install @laplace.live/event-bridge-sdk

Usage

import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const client = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token", // If auth is enabled
});

// Connect to the bridge
await client.connect();

// Listen for specific events
client.on("message", (event) => {
  console.log("Received message:", event);
});

// Listen for all events
client.onAny((event) => {
  console.log("Received event:", event.type);
});

Connection Options

LaplaceEventBridgeClient accepts the following optional connection settings:

Prop

Type

Server Role

SDK v1.2.0 and later can connect as the event producer. With role: 'server', each LaplaceEvent passed to send() is broadcast by the bridge to all clients:

import { LaplaceEventBridgeClient } from "@laplace.live/event-bridge-sdk";

const producer = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token: "your-auth-token",
  role: "server",
});

await producer.connect();

function broadcast(event: Parameters<typeof producer.send>[0]) {
  producer.send(event);
}

The server role is an event-producing endpoint connected to a running standalone Event Bridge server; it does not start the bridge server itself. The default client role receives events. Its send() calls are acknowledged but are not relayed to other connections. Event Fetcher Bridge Mode produces events internally and ignores incoming messages other than heartbeat pongs, so it cannot relay messages from SDK producers.

Connection State

onConnectionStateChange() immediately invokes a newly registered handler with the current state, so detail can be undefined on that first call. Later transitions provide the close reason and current reconnect count when available:

client.onConnectionStateChange((state, detail) => {
  console.log(state, detail?.reconnectAttempts);

  if (detail?.closeEvent) {
    console.log(detail.closeEvent.code, detail.closeEvent.reason);
  }
});

console.log(client.getReconnectAttempts());

getReconnectAttempts() returns the attempts made during the current outage, or 0 while connected or idle.

Prop

Type

Room Discovery

When the server is a LAPLACE Event Fetcher in bridge mode, it exposes an /info HTTP endpoint listing the configured rooms. The SDK can fetch it without an active WebSocket connection — useful for letting users pick which rooms to receive.

Use the client.getInfo() method (reuses the client's url / token):

const client = new LaplaceEventBridgeClient({
  url: "ws://localhost:9696",
  token,
});

const info = await client.getInfo();
if (info) {
  console.log(`Fetcher v${info.version} exposes ${info.rooms.length} room(s)`);
  for (const room of info.rooms) {
    console.log(`${room.roomId}: ${room.username ?? "unknown"}`);
  }
} else {
  // Plain Event Bridge server or an older fetcher — fall back to manual entry.
}

Or the standalone fetchInfo() function, which needs no client object:

import { fetchInfo } from "@laplace.live/event-bridge-sdk";

const info = await fetchInfo({ url: "ws://localhost:9696", token, signal });

Both resolve to null (they never throw) when /info is unavailable — an old fetcher, a plain Event Bridge server, an aborted request, or any network/parse error — so callers can silently fall back to manual room entry.

The returned shapes are FetcherInfo and FetcherRoom, both exported from the SDK:

import type { FetcherInfo, FetcherRoom } from "@laplace.live/event-bridge-sdk";

interface FetcherRoom {
  status: number; // 0 when resolved, otherwise an error code (e.g. 404)
  uid: number;
  roomId: number; // Canonical room id; matches the `origin` field on incoming events
  shortRoomId: number;
  username: string | null;
}

interface FetcherInfo {
  version: string;
  uptime: string;
  connectedAt: number;
  websocketBridge: boolean;
  websocketClients: number;
  rooms: FetcherRoom[];
}

LaplaceEvent

LaplaceEvent is the core type of the event bridge system, representing events exchanged between LAPLACE Chat and connected clients. Each event contains standardized data for various chat streams from Bilibili Live.

All events share a common type field that identifies the event category and additional fields specific to each event type.

You can read more about the event types in the Event Types documentation.

Use Cases

  • Integrate with Discord, OBS, VTube Studio
  • Create custom chat layouts in your preferred frontend
  • Connect to 3rd party services like streamer.bot or SAMMI
  • ...any other use case you can think of

Development

SDK Release Process

The SDK (@laplace.live/event-bridge-sdk) follows a structured release process using changesets for version management.

  1. Make your changes to the SDK in packages/sdk/

  2. Create a changeset to document your changes:

    bunx @changesets/cli
    • Select @laplace.live/event-bridge-sdk from the package list
    • Choose the appropriate version bump (patch/minor/major)
    • Write a clear description of the changes
  3. Commit your changes including the generated changeset file:

    git add .
    git commit -m "feat(sdk): your change description"

License

AGPL and MIT

Last updated on September 19, 2026

Tech otakus destroy the world