Skip to content

mertdogar/super-store

Repository files navigation

super-store

super-store

A reactive store, quietly backed by a CRDT.

Write it like in-memory state. Get real-time collaboration, offline persistence, and undo/redo — opt-in, behind the same API.

Docs · Getting started · Example


StoreValue<T> is a typed handle that behaves like a normal in-memory store — until you give it a document. Then the same handle is a Yjs CRDT: reads stay synchronous, writes stay a method call, and concurrent edits merge. Yjs stays hidden, even across the network.

import { StoreValue } from "@super-store/store"

// Fully local — identical to an in-memory store:
const counter = new StoreValue(0)
counter.subscribe(() => console.log(counter.getSnapshot()))
counter.set(1) // logs 1
counter.set(1) // no-op

// Make it collaborative — same API, opt-in. Relay bytes over any transport, no yjs import:
counter.onUpdate((update, { local }) => { if (local) bus.send(update) })
bus.on("message", (update) => counter.applyUpdate(update))

Packages

Package What it is
@super-store/store The StoreValue primitive. One runtime dep (yjs). No React.
@super-store/react useStore / useStoreSelector — tear-free hooks over useSyncExternalStore.
pnpm add @super-store/store          # yjs comes with it
pnpm add @super-store/react react    # for the hooks

Why

  • One API, two modes. A StoreValue is a plain value until you bind a doc; then it's a CRDT. Binding is lazy and cascades from the root.
  • Real merge. Backed by Yjs — concurrent edits converge per field, per array slot, per set member.
  • Collaboration without importing Yjs. encodeState / applyUpdate / onUpdate move CRDT bytes over any transport you own; a { local } flag breaks echoes. The wire is a CRDT; your code never sees Y.*.
  • Undo that respects peers. Opt-in per root; only your own edits revert; a remote merge is never undone.
  • Tear-free React. A cached, reference-stable snapshot; a remote merge re-renders like a local set().

See the docs for guides and the full API reference.

Example

examples/synced-canvas — a collaborative canvas: shapes synced live across tabs, a server that persists and co-writes, undo/redo, and an origin-tagged debug panel. State is a StoreValue; the wire is super-line. No yjs import in the app.

pnpm --filter @super-store/example-synced-canvas dev   # open http://localhost:5173 in two windows

Use with your AI agent

super-store ships an agent skill so your coding agent writes correct code:

npx degit mertdogar/super-store/skills/super-store .claude/skills/super-store

Other agents: see skills/super-store/AGENTS.md and the guide.

Development

pnpm install
pnpm build          # tsup -> dist (esm + cjs + d.ts) for each package
pnpm test           # vitest across packages
pnpm typecheck      # single root tsc --noEmit
pnpm lint           # oxlint
pnpm docs:dev       # local docs site (typedoc + vitepress)

Monorepo layout: packages/* (the libraries), examples/* (runnable demos), docs (the VitePress site).

License

MIT © Mert

Releases

No releases published

Packages

 
 
 

Contributors