brainstate

TopGunBuild/topgun · source

Snapshot 0 · 2026-11-04T12:47:27Z · Rust · Apache-2.0

Content fingerprint1c24e94c1bf8d995e5de8631347e3c47cd8e37332cf6e3e105505b073269230f

GitHub description at capture

Offline-first in-memory data grid with CRDT sync and a Rust server

README at capture

# TopGun

[![License](https://img.shields.io/github/license/TopGunBuild/topgun)](LICENSE) [![CI](https://img.shields.io/github/actions/workflow/status/TopGunBuild/topgun/rust.yml?branch=main&label=CI)](.github/workflows/rust.yml) [![Docker](https://github.com/TopGunBuild/topgun/actions/workflows/docker.yml/badge.svg)](https://github.com/TopGunBuild/topgun/actions/workflows/docker.yml) [![npm](https://img.shields.io/npm/v/@topgunbuild/client)](https://www.npmjs.com/package/@topgunbuild/client) [![Discord](https://img.shields.io/badge/discord-join-5865F2?logo=discord&logoColor=white)](https://discord.gg/NDpMG4dmJu) [![GitHub Stars](https://img.shields.io/github/stars/TopGunBuild/topgun?style=social)](https://github.com/TopGunBuild/topgun)

> **v2 — single-node core, in active hardening.** The TypeScript client and Rust server APIs are stable for single-node development and self-hosted evaluation. Before we recommend unattended production use, we're completing a public stabilization program: a machine-checked [invariant catalog](INVARIANTS.md) (every durability claim mapped to an enforcing test — gaps marked honestly), a crash-recovery proof harness, and a 72-hour endurance gate. Durability trade-offs are documented, not hidden (e.g. the default `batched` fsync acks before fsync — see the server docs). Cluster-mode (Raft-backed locks, cross-node replication) is in progress.

Build real-time apps that work offline. Local writes are instant and survive disconnects; reconnecting clients sync seamlessly with automatic conflict resolution. Self-host today: the server keeps your data in an embedded store, so there is no database to run. Apache-2.0, Rust server, TypeScript client. AI agents talk to your data natively through MCP.

TopGun v2 is a complete rewrite. It's not a port — it's a new architecture built to earn production trust; the status note above says what we do and don't yet claim.

**[Live Demo](https://demo.topgun.build/)** — try it in your browser

## Key features

- **Local-first**: Data lives in memory. Reads and writes never wait for network.
- **Offline support**: Changes persist to IndexedDB and sync when reconnected.
- **Conflict-free merges**: Automatic conflict resolution via LWW-Map and OR-Map, with causality tracked by logical clocks.
- **Efficient delta sync**: Only changed data moves over the wire, via Merkle tree comparison.
- **Pluggable storage**: Data lives in an embedded store inside the server (redb) — no database to run; bring your own client-side adapter.
- **Cluster-ready**: Server-side partitioning, pub/sub, and distributed locks (single-node stable; cluster-mode uses partition-routing — Raft-backed cluster locks in progress).
- **Rust server, TypeScript client**: Type-safe SDK with a high-performance Rust backend.
- **AI-native**: AI agents read and mutate your live data natively over MCP — the bundled `@topgunbuild/mcp-server` exposes your maps to Claude Desktop, Cursor, or any MCP client. Query, mutate, search, and subscribe without leaving your agent workflow.
- **Hybrid search**: Real-time hybrid search in one query — exact + full-text (BM25) + semantic vector search, RRF-fused, with live subscriptions. Pluggable embeddings (local Ollama or any OpenAI-compatible endpoint). Built-in HNSW vector database; works with your existing map data. Covers vector search, semantic search, hybrid search, RAG pipelines, and embeddings out of the box.

## Quick start

### Drop-in (5 minutes)

Scaffold a working app with one command:

```bash
npx create-topgun-app my-app
cd my-app && pnpm install && pnpm dev
```

This boots a Vite app with a working LWW-Map todo demo. For the backend, in a separate terminal:

```bash
npx @topgunbuild/server
```

No Rust toolchain required — this downloads a prebuilt binary for your platform and starts the server instantly. The server runs on `ws://localhost:8080` with embedded storage at `./topgun.redb` — writes survive restart, no separate database required. Stop with `Ctrl-C`, restart, and your data is still there. To back it up, see [Backup and restore](#production) below.

**Contributor / monorepo path:**

```bash
pnpm start:server
```

`pnpm start:server` uses a prebuilt binary when present and falls back to `cargo run --bin topgun-server --release` for contributors with the Rust toolchain.

For users who prefer containers, `docker compose up server` works too — it starts the server with its data on a named volume.

### Pull pre-built image (Docker)

If you have Docker installed, skip the build entirely:

```bash
docker pull ghcr.io/topgunbuild/topgun-server:latest
docker run -p 8080:8080 -e TOPGUN_NO_AUTH=1 ghcr.io/topgunbuild/topgun-server:latest
```

The image is multi-arch (linux/amd64 + linux/arm64) and is rebuilt on every push to `main`. For tagged releases use `:v2.0.0` (or `:2`, `:2.0`) instead of `:latest`.

### Production

Production deployments need a persistent path for the embedded store and explicit auth configuration. The TopGun v2 server is **single-node stable**; multi-node Raft consensus is on the roadmap (see [`/docs/roadmap`](https://topgun.build/docs/roadmap)).

**1. Storage**

There is no database to provision. The server keeps its data in an embedded store: a data directory plus a write-ahead log directory. Point both at a persistent volume (the image defaults are `/data/topgun-data` and `/data/topgun-wal`):

```bash
export TOPGUN_DATA_DIR=/data/topgun-data      # embedded store directory
export TOPGUN_WAL_DIR=/data/topgun-wal        # write-ahead log; keep it on the same volume
```

Upgrading from an earlier version moves an existing `TOPGUN_REDB_PATH` store file into the data directory once, by itself, and keeps the old file as `{TOPGUN_REDB_PATH}.pre-migration`; copy that file off the machine before upgrading. See the `Changed (on-disk format)` entry of [CHANGELOG.md](CHANGELOG.md).

**2. Server-side env vars**

```bash
export JWT_SECRET=<random-32-byte-secret>     # Required for signed tokens
export TOPGUN_NO_AUTH=0                       # 0 = enforce auth, 1 = dev-only bypass
# ACL config: see /docs/security for per-map and per-op rules
```

**3. Single-node deployment**

Single-node is fully consistent and stable for workloads that fit one server; the stabilization gates we're completing before recommending unattended production use are public ([INVARIANTS.md](INVARIANTS.md) + the [roadmap](https://topgun.build/docs/roadmap)):

```bash
docker compose up --build
# Or start the server directly (no Rust toolchain required)
npx @topgunbuild/server
# Contributor / monorepo path (has cargo):
# cargo run --bin topgun-server --release
```

**4. Multi-node cluster** *(on roadmap — Raft consensus)*

Multi-node deployments today use partition-routing without Raft consensus. **Cluster-safe distributed locks and split-brain protection require Raft, which is on the roadmap.** See [`/docs/roadmap`](https://topgun.build/docs/roadmap) for status.

**5. Backup and restore**

Back up by stopping the server (`SIGTERM` drains the write buffer and syncs the log) and copying **both** the whole data directory (`TOPGUN_DATA_DIR`) and the WAL directory (`TOPGUN_WAL_DIR`). Restore by putting both back with the server stopped, then starting it. The data directory alone is not the whole state: acknowledged writes that are not yet in it live in the WAL directory. A copy of a running server's directory is not a supported backup. Operational backup tooling beyond this is planned.

**6. Monitoring hooks** *(coming)*

Prometheus metrics endpoint and structured-log hooks are planned.

**Client wiring (both paths):**

<!-- doctest run reason="flagship wiring — executed against the live server in CI" -->
```typescript
import { TopGunClient } from '@topgunbuild/client';
import { IDBAdapter } from '@topgunbuild/adapters';

const client = new TopGunClient({
  serverUrl: 'ws://localhost:8080',  // optional — omit for local-only
  storage: new IDBAdapter(),
});
client.start();

// Reactive read — fires immediately and on every change
const todos = client.getMap('todos');
todos.subscribe((entries) => render(entries));

// Optimistic write — applies locally, syncs in background
todos.set('todo-1', { text: 'Buy milk', done: false });
```

With React:

```tsx
import { TopGunProvider, useQuery, useClient } from '@topgunbuild/react';

function App() {
  return (
    <TopGunProvider client={client}>
      <TodoList />
    </TopGunProvider>
  );
}

function TodoList() {
  const client = useClient();
  const { data, loading } = useQuery('todos');

  if (loading) return <div>Loading...</div>;

  const toggleTodo = (todo) => {
    const todosMap = client.getMap('todos');
    todosMap.set(todo.id, { ...todo, done: !todo.done });
  };

  return (
    <ul>
      {data.map((todo) => (
        <li key={todo.id} onClick={() => toggleTodo(todo)}>
          {todo.text}
        </li>
      ))}
    </ul>
  );
}
```

### Hybrid search (vector + full-text + exact)

TopGun supports tri-hybrid search — exact key lookup, BM25 full-text, and semantic vector search — fused with RRF into a single ranked result. Subscriptions update in real time as data changes.

```tsx
import { useHybridSearch } from '@topgunbuild/react';

function DocSearch({ query }: { query: string }) {
  const { results, loading } = useHybridSearch('docs', query, {
    methods: ['fullText', 'semantic'],  // HybridSearchMethod: 'exact' | 'fullText' | 'semantic'
    k: 10,
    minScore: 0.3,
  });

  if (loading) return <p>Searching…</p>;

  return (
    <ul>
      {results.map((r) => (
        <li key={r.key}>
          {r.key} — score {r.score.toFixed(3)}
          <small>
            {' '}(BM25: {r.methodScores?.fullText?.toFixed(3)},
            semantic: {r.methodScores?.semantic?.toFixed(3)})
          </small>
        </li>
      ))}
    </ul>
  );
}
```

> **Semantic search** requires server-side embedding config (`VectorConfig` on the server — set `TOPGUN_VECTOR_INDEX_PATH` and configure your embedding provider). `fullText` and `exact` work fully offline. See the [Vector & hybrid search guide](https://topgun.build/docs/guides/vector-and-hybrid-search).

## Documentation

Full docs: [topgun.build/docs](https://topgun.build/docs)

## Packages

| Package | Description |
|---------|-------------|
| `@topgunbuild/core` | CRDTs, Hybrid Logical Clock, Merkle trees, message schemas |
| `@topgunbuild/client` | Browser/Node.js SDK with IndexedDB persistence |
| `server-rust` | Rust WebSocket server (axum), clustering, embedded redb storage |
| `core-rust` | Rust port of CRDT primitives, depended on by `server-rust` (internal) |
| `@topgunbuild/react` | React hooks: `useQuery`, `useMap`, `useMutation`, `useTopic` |
| `@topgunbuild/adapters` | Storage adapters: IndexedDB |
| `@topgunbuild/adapter-better-auth` | Better Auth integration |
| `@topgunbuild/mcp-server` | MCP server for AI agents (Claude Desktop, Cursor) |
| `@topgunbuild/schema` | Shared Zod schemas + types |
| `create-topgun-app` | Scaffold a TopGun app in one command (`npx create-topgun-app my-app`) |

## Running locally

```bash
# Start the server — no Rust toolchain required
npx @topgunbuild/server

# Or start with Docker (data kept on a named volume)
docker compose up --build

# Contributor / monorepo path (has cargo):
# cargo run --bin topgun-server --release

# Or run the example app
cd examples/notes-app
pnpm install
pnpm start
```

## Performance

Measured on Apple M1 Max, 200 concurrent WebSocket connections, using the in-process load harness (`packages/server-rust/benches/load_harness/`):

| Mode | Throughput | Latency |
|------|-----------|---------|
| Fire-and-forget | **483K ops/sec** | — |
| Fire-and-wait | **~37K ops/sec** | **1.5ms p50** |

> Numbers are from an in-process load harness on Apple M1 Max with 200 concurrent connections. Performance on your hardware will differ. See [`packages/server-rust/benches/load_harness/baseline.json`](packages/server-rust/benches/load_harness/baseline.json) for CI thresholds and [`packages/server-rust/docs/profiling/FLAMEGRAPH_ANALYSIS.md`](packages/server-rust/docs/profiling/FLAMEGRAPH_ANALYSIS.md) for methodology.

## Coming from X

Migrating from another sync stack? Each guide names what TopGun does not replace, up front.

| Coming from | Why migrate | Migration guide | Status |
|-------------|-------------|-----------------|--------|
| Firebase Realtime | SQL, FTS, no vendor lock-in | [Guide](https://topgun.build/docs/guides/migrating-from-firebase) | Live |
| Y.js / Automerge | Server backend + SQL queries | [Guide](https://topgun.build/docs/guides/migrating-from-yjs) | Live |
| Replicache | Open source, no SaaS invoice | [Guide](https://topgun.build/docs/guides/migrating-from-replicache) | Live |
| Supabase Realtime | Offline-first, CRDT auto-merge | [Guide](https://topgun.build/docs/guides/migrating-from-supabase-realtime) | Live |
| Liveblocks | Self-hosted option | (planned) | Q3 2026 |

## Performance Testing

### Quick Smoke Test
```bash
pnpm test:k6:smoke
```

### Full Throughput Benchmark
```bash
pnpm test:k6:throughput
```

### Micro-Benchmarks (CRDT operations)
```bash
pnpm --filter @topgunbuild/core bench
```

See [packages/server-rust/benches/load_harness/](packages/server-rust/benches/load_harness/) and the [Performance tuning guide](https://topgun.build/docs/deploy/performance) for details.

## AI Agents

TopGun ships with a built-in MCP (Model Context Protocol) server, enabling AI assistants like Claude Desktop and Cursor to query and mutate your live data through natural language.

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "topgun": {
      "command": "npx",
      "args": ["@topgunbuild/mcp-server"],
      "env": {
        "TOPGUN_URL": "ws://localhost:8080"
      }
    }
  }
}
```

Full guide: [topgun.build/docs/guides/mcp-server](https://topgun.build/docs/guides/mcp-server)

## Contributing

PRs welcome. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the dev workflow (fork, branch, test, PR).

All contributions require signing the [Contributor License Agreement](.github/CLA.md) — the [cla-assistant.io](https://cla-assistant.io) bot prompts automatically on PR open. Takes ~30 seconds; you sign once.

## Community

- **Discord**: [discord.gg/NDpMG4dmJu](https://discord.gg/NDpMG4dmJu) — ask questions, share what you're building
- **GitHub Discussions**: [github.com/topgunbuild/topgun/discussions](https://github.com/topgunbuild/topgun/discussions) — longer-form Q&A and proposals
- **GitHub Issues**: [github.com/topgunbuild/topgun/issues](https://github.com/topgunbuild/topgun/issues) — bug reports and feature requests

## TopGun v1

Looking for the original gun.js TypeScript port? See the [`legacy-v1`](https://github.com/TopGunBuild/topgun/tree/legacy-v1) branch (unmaintained).

---

Built by [Ivan Kalashnik](https://github.com/ivkan)