Full-stack Go · one binary · zero external services
Your stack is ready.
Come build.
Not a framework. One binary.
Database, auth, realtime, background jobs, durable workflows, offline sync and an LLM client — in one self-contained Go binary.
Live demo: gogogo.calionauta.com — sign in as demo1@demo.app / demo1234456 (demo2@demo.app same password for two-user contention).
Start with the installer
curl -sSfL https://raw.githubusercontent.com/calionauta/gogogo/master/install.sh | sh -s -- --run
Needs curl and git — that's it. The command does the rest. Getting started →
AI-ready
You decide what to build. Agents handle the how.
Deterministic stack, scriptable installer, tool calls — everything on this page is built for agents to drive without babysitting. Why flat beats framework: the architecture decision →
Deterministic stack
The same choices in every project — agents stop re-deciding.
SCOPE on every file
Tagged Core (customize, never remove), Plugin (env-off), or Feature (delete it) — agents know what is safe to trim. Scope taxonomy →
Lint tuned for AI-written code
golangci-lint + datastar-lint + repo guard rules catch unchecked errors, leaked contexts, and template mistakes — enforced in hooks and CI, taught to agents via the gogogo-coding-standards skill.
Docs change with the code
One place describes behavior — updated in the same commit, never stale.
Humans type. Agents call.
GOGOGO CLI
cmd/gogogo · stdlib-only, no deps
--run— scaffold a repo and run it, one commandadvise— which lib or language fits the use-case--dry-run— preview the plan as JSON, zero changes--yes— scaffold, trim, prove it buildsadd— bring a trimmed unit back--check— verify markers, catch drift
Pin --no-tui --yes · never delete on an assumption
GOGOGO-MCP
cmd/gogogo-mcp · stdio, no port, no deploy
advise_stack— same guidance asadvisecapabilities_list— full capability registrytrim_plan— preview, changes nothingtrim_apply— scaffold, needsconfirm:truecheck_tree— drift verdict per unitadd_unit— restore a unit, needsconfirm:true
One JSON block in your client config · setup guide →
Prerequisite — install the binary, once
curl -sSfL https://raw.githubusercontent.com/calionauta/gogogo/master/install.sh | sh
Puts gogogo + gogogo-mcp in ~/.local/bin (or build from source: cd cmd/gogogo-mcp && go build -o gogogo-mcp .). Below, replace ~ with your absolute home path (echo $HOME) — clients spawn without a shell, so it may not expand.
{ "mcpServers": { "gogogo": { "command": "~/.local/bin/gogogo-mcp" } } }
Save as .mcp.json in your project (shared with the team), or run claude mcp add gogogo -- ~/.local/bin/gogogo-mcp for just you. Verify: claude mcp list, then restart Claude Code.
[mcp_servers.gogogo]
command = "~/.local/bin/gogogo-mcp"
In ~/.codex/config.toml (every project) or .codex/config.toml (this project, must be trusted). Verify: /mcp in session, or codex mcp list.
opencode mcp add gogogo -- ~/.local/bin/gogogo-mcp
Or in opencode.json: "mcp": {"gogogo": {"type": "local", "command": ["~/.local/bin/gogogo-mcp"]}}. Verify: opencode mcp list.
pi mcp add gogogo -- ~/.local/bin/gogogo-mcp
Pi 1.0 reads the standard mcpServers format too — migrating from another client just works. Verify: pi mcp list (exits 1 on invalid entries).
In the box
Every choice already made.
Decisions you would otherwise spend weeks on. Each one is documented with its trade-offs in stack layers — and why Go won in the thesis →.
No Docker. No Redis. No Postgres. No JS build step.
Core — always in (customize, never remove)
Database and auth — zero config
Turso · embedded SQLite
Cookie sessions and file-local storage. No separate service to run.
Always in
Roles and permissions without a service
Casbin + users.role
Roles ride the user row; one Casbin model enforces them at the mux. Embedded policy by default, DB-backed when rules must change at runtime.
Always wired · enforce: RBAC_ENABLED=true
Reactive UI with no JS framework
Templ + Datastar over SSE
Type-safe templates generated at build time, ~12 KiB client. A broken template is a compile error.
Always in
Background jobs with retry
goqite + SSE Hub
goqite executes with exponential backoff + jitter; the SSE Hub streams progress to the browser. No Redis.
Always in
Secrets encrypted at rest
age + ~/.secrets/
Decrypted at boot. No vault, no cloud dependency.
Always in
Plugin — on by default (env var to switch off)
Durable multi-step workflows
DagNats over JetStream
Declarative JSON. Kill the process mid-run and it resumes where it left off.
Off: DAGNATS_ENABLED=false
Broadcast across instances
NATS JetStream
Two or more instances behind a load balancer converge. Safe to enable on one.
Off: NATS_ENABLED=false
AI features on any provider
GoAI + ai-credits
Injectable LLM interface, plus optional credits and BYOK billing.
Off: unset GOAI_API_KEY
Offline-first sync
Service Worker + Leaf Node
Offline edits queue locally and replay on reconnect; replays never duplicate.
Off: OFFLINE_SYNC_ENABLED=false
Two UI skins, one binary
DaisyUI v5 · Basecoat
Switchable at runtime with UI_SKIN or ?skin=.
Off: UI_SKIN=daisyui
Room ownership without races
GoAkt grains
One grain per room: heartbeat roster plus an exactly-one presenter lock, supervised with restart budget. Demo at /room/ with a crash hook.
Off: GOAKT_ENABLED=false
Feature — optional extras (keep it or delete it)
Collaborative whiteboard
Loro CRDT + Rough.js
Presence cursors, offline outbox, Turso-persisted snapshots.
Delete: features/whiteboard/
Shared notes
Loro Text + SSE Hub
Concurrent typing that merges, presence and typing indicators, offline outbox.
Delete: features/notes/
Ask AI (generative UI)
Catalog + SSE morphs, no client JS
The model picks cards, tables and sections from a fixed catalog; the server renders them. Keyless demo included. Proves constrained generation with unknown-type fail-closed.
Delete: features/genui/
Review loop
Genkit flows (plugin) + GoAI + Jev judge
A writer and a critic iterate, then a classifier judge delivers the verdict. Typed flows, per-step traces, any Jev-compatible judge via env. Proves a multi-role loop with per-role cost attribution and confidence cascade.
Delete: features/review/ · drops the genkit plugin
Desktop apps on the same backend
Wails v3 · gogpu/ui
Wails ships a desktop app with offline edge sync; gogpu/ui is a pure-Go window with no webview and no HTTP.
Delete: cmd/desktop/, cmd/gui/
Todo reference app
SSE Hub record-sync
Full CRUD with per-user live updates. Copy the pattern, then remove it.
Delete: features/todo/
Room presence demo
GoAkt grains
Heartbeat roster plus an exactly-one presenter lock, supervised with restart budget. Copy the pattern for per-entity features, then remove it.
Delete: features/room/
What makes it different
Everything async your app will need.
Already inside.
Every web app eventually needs a queue, a workflow runtime, a collaboration layer, a realtime layer, and an owner for shared state. They solve different problems, so gogogo compiles all of them into one build — and lets you switch each off with a single environment variable when you don't need it.
Background jobs that update the UI
goqite + SSE Hub
Always on. Work longer than ~50ms goes here instead of blocking a request — progress streams back to the browser.
Workflows that survive a restart
DagNats over JetStream
Declarative JSON. Kill the server mid-run; it resumes at the last incomplete step.
Collaboration without data loss
Loro CRDT
Offline edits merge with no last-write-wins loss. Ops converge idempotently.
Live record updates, scoped per user
SSE Hub record-sync
The owner column decides who sees what — no extra channel to secure.
Ephemeral UI signals
SSE Hub over Datastar
Toasts, client counts, workflow progress — signals, not database-shaped events.
Broadcast across instances
NATS JetStream
Run two or more instances behind a load balancer and records converge. Safe to enable on one.
Room ownership without races
GoAkt grains
One addressable owner per room: heartbeat roster plus an exactly-one presenter lock, supervised with restart budget.
Seven layers, one make build. No build tags, no
stub files, no matrix. Read the async layers doc →
Featherweight client
Kilobytes of JS, not megabytes.
The backend is the source of truth — the browser holds ephemeral intent and cache, never authority. So the client stays tiny: measured vendored JS per feature (full table).
Todo, Room, Landing, Config
0 KB of extra JS
Server-rendered pages. No client code beyond the shared core.
Shared notes
~19 KB raw · ~7 KB gzip
Collaborative editing, presence, carets — one vendored file, no dependency.
Collaborative whiteboard
~48 KB raw · ~16 KB gzip
Canvas wiring plus the hand-drawn renderer. Still smaller than most framework runtimes alone.
Shared core, every page
~40 KB raw · ~16 KB gzip
Datastar plus theming. That is the whole client platform.
Safe to trim
Delete what you don't need, without guessing.
Every file in the codebase carries a SCOPE annotation on two axes: where it lives, and what happens if you delete it. A linter enforces it, so you never have to guess whether a directory is load-bearing.
Core
The binary does not work without it.
config · db · internal/queue
internal/secrets · features/app
router · web/resources
Customize, never remove.
Plugin
The binary works but loses a capability.
internal/nats · internal/dagnats
internal/llm · internal/collab
internal/datastar · internal/goakt
web/skins
Swap, or delete + remove the wiring call.
Feature
A demo or add-on.
features/todo · features/whiteboard
features/room · features/notes
features/genui · features/landing · features/config
features/onboarding · features/credits
Keep as reference, then remove.
make check-scope runs in CI and in your pre-commit
hook. Scope taxonomy →
The exception
Go for everything. Zig only as an exception.
Zig enters in one case: a proven native need — a profiled hot kernel, a codec, an OS integration. Everything else stays Go.
Start here
Run. Ship.
The installer scaffolds your repo from this template, renames it, and trims the plugins and features you skip. Nothing to install first except Go.
curl -sSfL https://raw.githubusercontent.com/calionauta/gogogo/master/install.sh | sh -s -- --run