clickclack/docs/quickstart.md
2026-05-08 08:11:08 +01:00

3.4 KiB

title description
Quickstart From a fresh clone to a running ClickClack instance with a real owner, a workspace, a channel, and a bot — in about five minutes.

Quickstart

The smallest useful ClickClack: a real owner account, one workspace, one channel, a session token in your shell, a bot that posts a message. About five minutes.

1. Boot the server

pnpm install
pnpm build
go run ./apps/api/cmd/clickclack serve

Open http://localhost:8080 for the product website. Open http://localhost:8080/app for the chat app with a Local Captain user already signed in via the dev fallback. That's the empty-dev path — useful for poking around, not what you want long-term.

2. Replace the dev user with a real owner

go run ./apps/api/cmd/clickclack admin bootstrap \
  --name "Peter" --email steipete@gmail.com
# prints usr_...

If the DB already has a user (the dev fallback created one), bootstrap returns that user's ID instead of making a new one. Reset by deleting data/clickclack.db if you want a clean slate.

3. Mint a session

Magic-link tokens are mintable from the CLI. Generate one and exchange it for a session token:

TOKEN=$(go run ./apps/api/cmd/clickclack admin magic-link create \
  --email steipete@gmail.com --name "Peter")

SESSION=$(go run ./apps/api/cmd/clickclack login \
  --magic-token "$TOKEN" --plain --no-store)
# prints ses_...

That ses_... is what bots and CLIs put in Authorization: Bearer. The browser already has it as the cc_session cookie if you ran consume from the SPA.

To store the session for future CLI commands, omit --no-store.

4. Make a workspace and a channel

You can use the SPA, or hit the API directly:

WORKSPACE=$(curl -s -X POST http://localhost:8080/api/workspaces \
  -H "authorization: Bearer $SESSION" \
  -H 'content-type: application/json' \
  -d '{"name":"Tide Pool"}' | jq -r .workspace.id)

CHANNEL=$(curl -s -X POST "http://localhost:8080/api/workspaces/$WORKSPACE/channels" \
  -H "authorization: Bearer $SESSION" \
  -H 'content-type: application/json' \
  -d '{"name":"general"}' | jq -r .channel.id)

echo "workspace=$WORKSPACE channel=$CHANNEL"

5. Post your first message

go run ./apps/api/cmd/clickclack \
  --server http://localhost:8080 \
  --token "$SESSION" \
  send --channel "$CHANNEL" "click. clack."

curl -s -X POST "http://localhost:8080/api/channels/$CHANNEL/messages" \
  -H "authorization: Bearer $SESSION" \
  -H 'content-type: application/json' \
  -d '{"body":"click. clack."}' | jq .message.body

Refresh the SPA — the message is there. Now hover it and click the thread icon to start a thread; replies stream live over the WebSocket.

6. Run the bot example

CLICKCLACK_URL=http://localhost:8080 \
CLICKCLACK_TOKEN="$SESSION" \
CLICKCLACK_CHANNEL_ID="$CHANNEL" \
CLICKCLACK_TEXT="clack from a bot" \
pnpm --filter @clickclack/example-bot start

It posts a single message via the TypeScript SDK. Use it as a template — the SDK is framework-neutral, so the same code runs in Node, Bun, Deno, browsers, or Cloudflare Workers.

Where to go next

  • Architecture — how the parts fit.
  • Realtime — cursor recovery and event types.
  • Auth — the four ways to identify a caller.
  • Deployment — running this for real, not just on a laptop.