Help us shape the future of Go! Take the 2026 Go Developer Survey

gogogofullstacktemplate

package module
v0.33.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2026 License: MIT Imports: 0 Imported by: 0

README ΒΆ

gogogo

gogogo

Landing page Β· Docs Β· Releases Β· CI

Your stack is ready. Come build. Every decision favors practical outcomes over abstract ideals. The stack optimizes for simplicity, consistency, and shipping software with minimal friction.

Every web project starts with the same conversation β€” pick a database, auth, router, reactive frontend, task queue… β€” and the project stalls at the decisions, installations, and configurations. Not at the code. This template answers those decisions once, ships them wired together, and documents how to change or remove each piece.

πŸ“– Docs (single source of truth)

The manual lives on the site, not in this file: calionauta.github.io/gogogo/docs/

Page index (20 pages)

One-liners mirror the docs site manifest (site/build.mjs).

Get started

  • overview β€” what gogogo is, who it is for, and the six async layers it ships.
  • getting-started β€” clone, run, first five minutes, and the commands you need.

Core

  • architecture β€” directory layout, dependency direction, entry points, and route wiring gotchas.
  • stack-layers β€” every dependency and why it is in the box.
  • async-layers β€” the six async layers, PB realtime vs SSE Hub, cross-instance and offline sync.
  • features β€” every capability and its runtime opt-out.
  • scope-taxonomy β€” Core / Plugin / Feature: the rule for deciding what is safe to delete.
  • configuration β€” every environment variable and runtime constant.
  • native-zig β€” Go-first policy: why Zig is an exceptional native boundary, plus the agent decision procedure.

Frontend

  • todo-example β€” the Todo reference implementation and the contract to imitate.
  • ui-skins β€” pluggable DaisyUI / Basecoat / Morpheus skins and the plugin contract.
  • ui-sounds β€” vendored cuelume sound feedback and its accessibility contract.

Ship

  • deploy β€” server layout, first-time setup, deploy workflow, build pipeline and version badge.
  • desktop-mobile β€” Wails v3 desktop/mobile, edge sync, and the native window PoC.
  • admin-dashboard β€” admin surfaces, the two-cookie rule, and the DagNats console.
  • llm-and-credits β€” GoAI configuration and the optional ai-credits / BYOK plugin.

Operate

  • local-ci β€” the five-tier feedback loop and make signoff.
  • code-quality β€” the 27 linters, how to scope them, and the Datastar-specific rules.
  • troubleshooting β€” symptoms and where they actually come from.
  • dagnats-bootstrap-workaround β€” the upstream DagNats bug behind the trigger console, and the removable seed that works around it.

Plus ARCHITECTURE.md β€” the canonical annotated dependency graph, and AGENTS.md β€” the working rules for human and AI agents in this repo.


πŸš€ Quick start

This repo is a GitHub template β€” click Use this template to get your own copy, then rename it. Do not build inside a clone of the template itself: your module path would stay github.com/calionauta/gogogo and deploys would target the template's server directory.

# 1. Scaffold with the installer: one command installs (binaries +
#    Go toolchain when missing), asks name/owner/plugins/features, renames,
#    trims what you skip, writes AGENTS.md, then `make dev` takes this
#    terminal β€” Ctrl-C stops dev. Needs curl + git, nothing else.
curl -sSfL https://raw.githubusercontent.com/calionauta/gogogo/master/install.sh | sh -s -- --run

# With Go already installed, the equivalent without curl|sh:
# go run github.com/calionauta/gogogo/cmd/gogogo@latest --run

# Manual fallback (no installer):
# gh repo create my-app --template calionauta/gogogo --clone
# cd my-app
# make rename NAME=my-app          # add OWNER=myorg if not under calionauta
# make site                        # regenerate the published docs
# make dev                         # run

This command needs Go and git (checked up front) β€” or curl + git via the binary install in CLI & MCP below, where install.sh bootstraps Go when missing. Open http://localhost:8080 for the landing page, then http://localhost:8080/todo for the demo (sign in with the seeded demo@demo.app / demo1234456).

make rename only rewrites this project's identity. Sibling repos under the same owner (ai-credits, datastar-lint, pi-leakguard) are real dependencies and are left alone.

One make build compiles everything. No build tags, no feature matrix. Opt out at runtime with env vars (NATS_ENABLED=false, DAGNATS_ENABLED=false).

In the box

Layer Choice Why
Language Go 1.27 Fast compilation, easy deploy, lean runtime. Go-first: Zig only as an exceptional native escape hatch (native-zig)
Zero-config database, auth and API PocketBase (embedded SQLite) Zero-config auth, REST, file storage, and an admin UI at /_/ β€” no separate service
Reactive UI with no JS framework Templ + Datastar (SSE) + Tailwind v4 Server-rendered HTML, ~12 KiB client, no JS framework build step
Three UI skins in one binary DaisyUI v5 (default) + Basecoat + Morpheus Three skins compiled into one binary, switchable at runtime
Background jobs with retry goqite + SSE Hub Background jobs streamed to the browser. No Redis
Workflows that survive a restart DagNats Multi-step workflows as declarative JSON; resume after a mid-run kill
Shared state that merges offline edits Loro CRDT + Rough.js Conflict-free state with no last-write-wins data loss
Realtime for one instance or many PocketBase realtime + NATS JetStream Per-user record push, plus cross-instance broadcast
AI features on any provider GoAI + optional ai-credits Any OpenAI-compatible provider; optional billing ledger + BYOK
Secrets encrypted at rest age + ~/.secrets/ Local encryption. No vault, no cloud
Desktop apps on the same backend Wails v3 + gogpu/ui Native shells over the same backend, plus a no-HTTP frontend
Linting tuned for AI-written code golangci-lint (27) + datastar-lint Tuned for LLM-authored code: unchecked errors, context leaks, lost context propagation

Full table with the reasoning behind each choice: stack-layers.

Everything async your app will need

Six complementary layers, already inside, each with its own opt-out:

Background jobs that update the UI   β†’ goqite + SSE Hub (always on)
Workflows that survive a restart     β†’ DagNats as JSON (DAGNATS_ENABLED=false)
Collaboration without data loss      β†’ Loro CRDT (remove internal/collab/)
Live record updates, scoped per user β†’ PB realtime (always on)
Ephemeral UI signals                 β†’ SSE Hub via Datastar (always on)
Broadcast across instances           β†’ JetStream (NATS_ENABLED=false)

Records flow through PocketBase's own realtime channel β€” scoped per user by the collection's access rules, free of charge. The SSE Hub is reserved for ephemeral signals (toasts, client counts, workflow progress). Mixing those two up is the most common mistake in Datastar apps; async-layers explains why the split matters.

Capabilities

Every capability is always compiled. Each has a documented opt-out.

Capability Opt-out
Todo app + PocketBase realtime, stacked toasts, sound feedback delete features/todo/
Queue + retry with exponential backoff, SSE lastRetry signal β€” (core)
AI Suggest via GoAI, or keyless simulated LLM for the demo no GOAI_API_KEY and SIMULATE_LLM=false
AI credits + BYOK relay + Stripe top-ups CREDITS_ENABLED=false
Collaborative whiteboard (CRDT + presence + offline outbox) delete features/whiteboard/
Durable WelcomeOnboarding workflow DAGNATS_ENABLED=false
Hybrid offline sync (Service Worker + Leaf Node) OFFLINE_SYNC_ENABLED=false
Pluggable persistence (pb ⇄ crdt) ENTITY_STORE=pb
Multi-instance realtime NATS_ENABLED=false
Public landing page + auth-gated config view delete features/landing/, features/config/
Wails v3 desktop/mobile + native window PoC delete cmd/desktop/, cmd/gui/

Infrastructure opts out with an env var. Product features opt out by deleting the package and its one wiring call β€” see features.

Core / Plugin / Feature

Every non-test .go file under internal/ and features/ carries a SCOPE annotation on two axes: layer (where it lives) and removal (what happens if you delete it). make check-scope enforces it in CI and in your pre-commit hook.

Annotation Meaning You would
removal=core πŸ”΄ The binary does not work without it Customize, never remove
removal=plugin 🟑 The binary works but loses a capability Swap, or delete + remove the wiring call
removal=feature 🟒 A demo or add-on Keep as reference, then remove

The rule for agents: never delete a removal=core file without asking; never keep a removal=feature file in production if the domain doesn't need it. Full taxonomy and per-package removal table: scope-taxonomy.

Try it live

What URL
Todo & Whiteboard demo gogogo.calionauta.com
Live PocketBase admin gogogo.calionauta.com/_/
Durable workflow console (DagNats) gogogo.calionauta.com/dagnats/

Sign in with demo@demo.app / demo1234456. The demo's users collection is locked β€” you can log in as the demo user but cannot create or delete accounts through the API or the dashboard (only the superuser can).

Commands

make dev           # Live reload with Air (regenerates templ + CSS)
make build         # Build binary (unified: everything included)
make ci-local      # Full local gate (= CI): templ, lint, css-check, race tests, build
make signoff       # ci-local + gh signoff stamp β€” the recommended pre-push gate
make setup         # Activate lefthook git hooks
make site          # Rebuild the docs site from docs/*.md

Full command reference: getting-started.

CLI & MCP (agent paths)

Humans get the guided installer above. Agents get the same engine (internal/installer) through two scripted paths β€” opinions first, preview second, mutation last. Full guides live in their own section: docs/cli.md and docs/mcp.md.

Path Use when Entry point
advise deciding what to keep (use-case β†’ keep/drop + off-switches + Go/Zig rule). Changes nothing go run ./cmd/gogogo advise --need "..." --format json
trim --dry-run previewing the scaffold as one JSON document --no-tui --dry-run --format json (add --yes to apply)
add / --check restoring a unit into a scaffolded checkout / verifying markers add <unit> --from <pristine> --dir <proj> [--dry-run|--yes]
MCP server tool calls instead of shell (advise_stack, capabilities_list, trim_plan, trim_apply, check_tree, add_unit) cmd/gogogo-mcp (own module, stdio) + one JSON block in the client config

Destructive paths refuse without explicit confirmation (--yes / confirm:true). Strategy and the foreign-codebase boundary: getting-started Β§0b–0c.

No Go on this machine? Tagged releases ship static binaries (gogogo + gogogo-mcp, checksummed) β€” and install.sh bootstraps a user-space Go toolchain when none is found (~/.local/go, no sudo, existing installs untouched). Same one-liner as the quick start above (it is the quick start β€” append anything after --run and it reaches gogogo):

Before you push

make ci-local locally is the same gate CI runs, and make signoff adds a git stamp. It catches ~95% of regressions in under 3 minutes instead of waiting on a CI round trip. The tier ladder (T1 format/build β†’ T5 signoff) and what each tier catches: local-ci.

Acknowledgements

Inspired by northstar by Zangster β€” a Go + NATS + Datastar + Templ + DaisyUI application starter.

License

MIT β€” see LICENSE. Open to feedback, PRs, and adaptations. If something doesn't make sense, if the stack doesn't fit your problem, or if you have a better idea, open an issue.

Documentation ΒΆ

Overview ΒΆ

SCOPE:core - DO NOT REMOVE - Module root package. Package gogogofullstacktemplate is the module root.

This file exists so the module root package is never empty: some Go toolchains treat an empty root package as a hard "no Go files" error when running `go test ./...`, which aborts the whole test gate. With this file present the root reports "[no test files]" instead.

The package name intentionally has no underscore: golangci-lint's revive linter rejects underscore-separated package names, and the module import path (github.com/calionauta/gogogo) is independent of the package name, so renaming is safe.

Directories ΒΆ

Path Synopsis
cmd
check-scope command
SCOPE:core - DO NOT REMOVE - SCOPE annotation linter (pre-commit gate).
SCOPE:core - DO NOT REMOVE - SCOPE annotation linter (pre-commit gate).
desktop command
Command desktop builds the Wails v3 native app shell around the exact same Go backend the web app uses (PocketBase + goqite queue + router + handlers).
Command desktop builds the Wails v3 native app shell around the exact same Go backend the web app uses (PocketBase + goqite queue + router + handlers).
gogogo command
Command gogogo scaffolds a new project from gogogo.
Command gogogo scaffolds a new project from gogogo.
gui command
SCOPE:layer=feature,removal=feature β€” gogpu/ui native window over the existing backend
SCOPE:layer=feature,removal=feature β€” gogpu/ui native window over the existing backend
web command
SCOPE:core - DO NOT REMOVE - Server entry point.
SCOPE:core - DO NOT REMOVE - Server entry point.
SCOPE:core - DO NOT REMOVE - Server configuration (env vars, secrets).
SCOPE:core - DO NOT REMOVE - Server configuration (env vars, secrets).
SCOPE:plugin - REMOVE if you don't need idempotent offline replay.
SCOPE:plugin - REMOVE if you don't need idempotent offline replay.
features
app
SCOPE:layer=feature,removal=core β€” AppContext (cross-cutting deps bundle) Package app provides the cross-cutting "application core" pattern for projects built on top of gogogo.
SCOPE:layer=feature,removal=core β€” AppContext (cross-cutting deps bundle) Package app provides the cross-cutting "application core" pattern for projects built on top of gogogo.
auth
SCOPE:layer=feature,removal=core β€” Auth middleware (cookie + login/logout) Package auth implements a single-user demo login on top of PocketBase's built-in auth API.
SCOPE:layer=feature,removal=core β€” Auth middleware (cookie + login/logout) Package auth implements a single-user demo login on top of PocketBase's built-in auth API.
config
SCOPE:layer=feature,removal=feature β€” Auth-gated read-only /config view (masked secrets)
SCOPE:layer=feature,removal=feature β€” Auth-gated read-only /config view (masked secrets)
credits
SCOPE:layer=feature,removal=plugin β€” the credits Service implements the llm.Biller seam so every Chat/ChatStream call (the internal/llm choke point) is metered.
SCOPE:layer=feature,removal=plugin β€” the credits Service implements the llm.Biller seam so every Chat/ChatStream call (the internal/llm choke point) is metered.
landing
SCOPE:layer=feature,removal=feature β€” Public marketing landing page (GET /)
SCOPE:layer=feature,removal=feature β€” Public marketing landing page (GET /)
sounds
templ: version: v0.3.1020
templ: version: v0.3.1020
store
SCOPE:layer=infra,removal=core β€” EntityStore interface (the contract every storage
SCOPE:layer=infra,removal=core β€” EntityStore interface (the contract every storage
store/crdtstore
SCOPE:layer=infra,removal=plugin β€” Loro CRDT-backed EntityStore strategy for todos
SCOPE:layer=infra,removal=plugin β€” Loro CRDT-backed EntityStore strategy for todos
store/pbstore
SCOPE:layer=infra,removal=core β€” REMOVE if you don't need PocketBase-backed storage
SCOPE:layer=infra,removal=core β€” REMOVE if you don't need PocketBase-backed storage
todo
SCOPE:layer=feature,removal=feature β€” Todo MVC example (reference implementation) To remove: delete features/todo/ and the todo block in router/router.go Init().
SCOPE:layer=feature,removal=feature β€” Todo MVC example (reference implementation) To remove: delete features/todo/ and the todo block in router/router.go Init().
todo/components
templ: version: v0.3.1020
templ: version: v0.3.1020
todo/handlers
SCOPE:layer=feature,removal=feature β€” Todo MVC example (reference implementation)
SCOPE:layer=feature,removal=feature β€” Todo MVC example (reference implementation)
whiteboard
SCOPE:layer=feature,removal=feature β€” Collaborative whiteboard (Loro CRDT canvas) Embedded static assets for the whiteboard feature: rough.min.js (Rough.js hand-drawn canvas rendering) and whiteboard.js (Datastar/SSE canvas wiring).
SCOPE:layer=feature,removal=feature β€” Collaborative whiteboard (Loro CRDT canvas) Embedded static assets for the whiteboard feature: rough.min.js (Rough.js hand-drawn canvas rendering) and whiteboard.js (Datastar/SSE canvas wiring).
internal
capabilities
SCOPE:layer=infra,removal=plugin β€” Capability registry: single source of truth for ids, kinds, runtime switches, and owned paths (consumed by cmd/gogogo, docs, and --help).
SCOPE:layer=infra,removal=plugin β€” Capability registry: single source of truth for ids, kinds, runtime switches, and owned paths (consumed by cmd/gogogo, docs, and --help).
collab
SCOPE:layer=infra,removal=plugin β€” Loro CRDT + DocStore + sync workers + presence To remove: delete internal/collab/ + features/whiteboard/ + router/whiteboard.go + router/collab_jetstream.go.
SCOPE:layer=infra,removal=plugin β€” Loro CRDT + DocStore + sync workers + presence To remove: delete internal/collab/ + features/whiteboard/ + router/whiteboard.go + router/collab_jetstream.go.
components
templ: version: v0.3.1020
templ: version: v0.3.1020
dagnats
SCOPE:layer=infra,removal=plugin β€” DagNats durable workflow engine To remove: delete internal/dagnats/, cmd/web/dagnats.go, router/onboarding_dagnats.go and dagnats_proxy_dagnats.go.
SCOPE:layer=infra,removal=plugin β€” DagNats durable workflow engine To remove: delete internal/dagnats/, cmd/web/dagnats.go, router/onboarding_dagnats.go and dagnats_proxy_dagnats.go.
datastar
SCOPE:layer=infra,removal=core β€” Datastar rendering helpers (RenderAndPatch, MergeSignals)
SCOPE:layer=infra,removal=core β€” Datastar rendering helpers (RenderAndPatch, MergeSignals)
installer
SCOPE:layer=infra,removal=plugin β€” installer engine: add units to existing checkouts (copy, rewire, prove)
SCOPE:layer=infra,removal=plugin β€” installer engine: add units to existing checkouts (copy, rewire, prove)
llm
SCOPE:layer=infra,removal=plugin β€” GoAI LLM client (used by Suggest) To remove: delete internal/llm/ + features/todo/handlers/llm_suggest.go.
SCOPE:layer=infra,removal=plugin β€” GoAI LLM client (used by Suggest) To remove: delete internal/llm/ + features/todo/handlers/llm_suggest.go.
llm/fakeserver
SCOPE:layer=infra,removal=plugin β€” GoAI LLM client (used by Suggest) Package fakeserver provides an httptest-compatible OpenAI Chat Completions fake for end-to-end tests of the GoAI integration without burning real tokens.
SCOPE:layer=infra,removal=plugin β€” GoAI LLM client (used by Suggest) Package fakeserver provides an httptest-compatible OpenAI Chat Completions fake for end-to-end tests of the GoAI integration without burning real tokens.
nats
SCOPE:layer=infra,removal=plugin β€” Enables cross-instance Leaf Node replicates, server consumer writes to server PocketBase).
SCOPE:layer=infra,removal=plugin β€” Enables cross-instance Leaf Node replicates, server consumer writes to server PocketBase).
queue
SCOPE:layer=infra,removal=core β€” Job queue (goqite) + Worker Pool Package queue implements the background job subsystem: a goqite-backed SQLite queue, an SSE hub for streaming progress to the browser, and a worker pool that dispatches messages through a typed HandlerRegistry.
SCOPE:layer=infra,removal=core β€” Job queue (goqite) + Worker Pool Package queue implements the background job subsystem: a goqite-backed SQLite queue, an SSE hub for streaming progress to the browser, and a worker pool that dispatches messages through a typed HandlerRegistry.
routeutil
SCOPE:layer=infra,removal=core β€” shared routing helper.
SCOPE:layer=infra,removal=core β€” shared routing helper.
secrets
SCOPE:layer=infra,removal=core β€” Secret management with age (age-encryption.org) Package secrets decrypts a per-project environment file using age (https://age-encryption.org).
SCOPE:layer=infra,removal=core β€” Secret management with age (age-encryption.org) Package secrets decrypts a per-project environment file using age (https://age-encryption.org).
server
SCOPE:layer=infra,removal=core β€” Server bootstrap (PocketBase, queue, router) Package server wires the binary's startup sequence shared by every frontend target (web, desktop, future mobile): PocketBase, the goqite queue, the todo handlers, and the HTTP routes.
SCOPE:layer=infra,removal=core β€” Server bootstrap (PocketBase, queue, router) Package server wires the binary's startup sequence shared by every frontend target (web, desktop, future mobile): PocketBase, the goqite queue, the todo handlers, and the HTTP routes.
SCOPE:core - /api discovery handler.
SCOPE:core - /api discovery handler.
scripts
agehelper command
Command agehelper is a tiny stand-in for the `age` / `age-keygen` CLIs, used by bin/init-secrets when neither binary is installed.
Command agehelper is a tiny stand-in for the `age` / `age-keygen` CLIs, used by bin/init-secrets when neither binary is installed.
web
resources
SCOPE:core - DO NOT REMOVE - Embedded static assets (CSS, JS, etc.).
SCOPE:core - DO NOT REMOVE - Embedded static assets (CSS, JS, etc.).
skins
templ: version: v0.3.1020
templ: version: v0.3.1020
skins/basecoat
Package basecoat implements the BasecoatUI (shadcn) skin.
Package basecoat implements the BasecoatUI (shadcn) skin.
skins/daisyui
Package daisyui implements the default DaisyUI skin.
Package daisyui implements the default DaisyUI skin.
skins/morpheus
Package morpheus implements the Morpheus web-component skin (Scope 3).
Package morpheus implements the Morpheus web-component skin (Scope 3).
skins/morpheus/neolib
templ: version: v0.3.1020
templ: version: v0.3.1020

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL