Skip to main content
Meridian is a self-hosted alternative to Liveblocks and PartyKit. Concurrent updates from multiple clients converge automatically using CRDTs — no operational transforms, no conflict resolution code on your end. Sub-millisecond merge latency on a single node. Deltas are broadcast over WebSocket as soon as an op is applied — no polling, no round-trips.

What it is

  • Server: Rust binary, single file, no external dependencies. Stores state in an embedded sled database.
  • SDK: TypeScript, Effect-based, msgpack wire protocol. Works in Node, Bun, and browsers.
  • Auth: Custom ed25519-signed tokens (smaller than JWT, constant-time verification).

Quickstart

1. Start the server
MERIDIAN_SIGNING_KEY=$(openssl rand -hex 32) docker compose up -d
2. Install the SDK
bun add meridian-sdk effect msgpackr
3. Connect and sync
import { Effect, Schema } from "effect";
import { MeridianClient } from "meridian-sdk";

const client = await Effect.runPromise(
  MeridianClient.create({
    url: "http://localhost:3000",
    namespace: "my-room",
    token: process.env.MERIDIAN_TOKEN!,
  })
);

const views = client.gcounter("gc:views");
views.increment(1);
views.onChange(v => console.log("views:", v));

CRDT types

TypeUse case
GCounterPage views, likes, download counts
PNCounterInventory, vote tallies
ORSetShopping cart, tag sets, collaborative lists
LwwRegisterUser profile, document title, config
PresenceWho’s online, cursor positions, typing indicators