Self-host · API-first · SQLite

Self-hostable chat with claws.

A self-hostable chat server with Slack-style threads, an OpenAPI-first surface, embedded SQLite, and a TypeScript SDK. One Go binary. Bring your own pincers.

Quickstart GitHub
go run ./apps/api/cmd/clickclack serve
ChannelsThreadsReactionsRealtimeSearchUploadsDMsWebhooksBots

Other ways to install →

Tiny chat. Big claws.

ClickClack is a self-hostable chat server that fits in a single Go binary. SQLite by default, an embedded Svelte SPA, Slack-style threads, durable realtime over a WebSocket pipe, and a framework-neutral TypeScript SDK so the bots feel at home.

It's built for small teams, internal tools, communities, and anyone who would rather host their own.

Product domain: clickclack.chat. App domain: app.clickclack.chat, with /app as the local path. Docs domain: docs.clickclack.chat.

#Why ClickClack

  • One binary, zero ceremony. Drop it on a box, point at a data directory,
  • reverse-proxy if you want TLS. SQLite ships inside.

  • Realtime that recovers. WebSocket is a pipe; SQLite is the truth. Reconnect
  • with a cursor and you're back, even after a long offline.

  • Threads that don't nest. One level deep, on purpose. Discussion stays
  • scannable.

  • Bots that aren't second-class. Same auth surface as humans, a typed
  • TypeScript SDK, a scriptable CLI client, and a Mattermost-shaped webhook for drop-in scripts.

  • Crustacean, lightly. Lobster mascot, claw reactions, :molting: status.
  • Normal controls stay normal.

#Five-minute test drive

pnpm install
pnpm build
go run ./apps/api/cmd/clickclack serve
# open http://localhost:8080

The dev fallback boots a default user, workspace, and channel so the SPA loads into something useful at /app. The root path is the product website. Disable it for anything that isn't a local clone.

Get the full quickstart →

#What's in the box

FeatureDoc
Channels, messages, edits, soft-deleteMessages
Slack-style threads, one level deepThreads
Reactions on every messageReactions
Realtime over WebSocket with cursor recoveryRealtime
SQLite FTS5 full-text searchSearch
Local file uploads + message attachmentsUploads
Workspace-scoped direct messagesDirect messages
Human and bot identitiesBots
Creating and installing bot tokensBot installs
Profile settings, handles, avatarsProfiles
Magic-link auth, GitHub OAuth, dev fallbackAuth
Guest waiting-room roles, approvals, timeouts, blocksModeration
Mattermost-shaped webhooks and slash commandsIntegrations
TypeScript SDK + bot exampleSDK

#Operate it

  • CLI — server, admin, backup/export, and remote chat client
  • commands.

  • Agent-friendly CLI — scriptable chat client commands
  • for humans, agents, and CI jobs.

  • Configuration — flag/env/file precedence.
  • Deployment — single binary, Docker, data layout, OAuth.
  • Bot installs — create bot identities and wire their
  • tokens into OpenClaw or SDK runtimes.

  • Development — pnpm scripts, monorepo layout, gates.
  • Releasing — GoReleaser targets, artifacts, and tag flow.

#Look under the hood

  • Architecture — durable vs realtime, where each
  • layer lives.

  • API overview — REST/WebSocket surface, auth headers.
  • Data model — tables, IDs, thread invariants.
  • SPEC.md — locked
  • V1 decisions, milestones, open questions.

#Status

V1 is in flight. The vertical slice — workspaces, channels, Markdown messages, threads, realtime, reactions, search, uploads, DMs, magic-link auth, GitHub OAuth, guest-room moderation, Postgres, R2 uploads, and Docker — is implemented. Multi-node websocket fanout, federation, voice/video, and full Mattermost compatibility are intentionally out of scope.

Made with ✦ and a little brine. The lobster is on duty.