Row Level Security, tested
Policies enforced in the database and integration-tested. Request JWT claims ride into every query through a scoped transaction, so the repository layer cannot skip tenant scoping (ADR-004).
A Go + HTMX SaaS starter built for agent-assisted development: a layered AI constitution and a halt-on-violation CI gate hold coding agents to the same rules as humans, and multi-tenancy is proven end-to-end by Postgres Row Level Security scoped by real Supabase identities and exercised by the demo app itself.
| Layer | Choice | Version |
|---|---|---|
| Language | Go (minimum 1.26.0) | 1.27.2 |
| Router | Chi | 5.5.0 |
| Templates | templ (typed props, no map[string]interface{}) | 0.3.1070 |
| Interactivity | HTMX + Alpine.js | 2.0.11 / 3.13.3 |
| Styling | Tailwind CSS with role-based design tokens | 4.3.3 |
| Database access | sqlc code generation + repository pattern | 1.31.1 |
| Migrations | golang-migrate | 4.19.1 |
| Auth and data | Supabase (GoTrue + PostgreSQL + RLS) | pgx 5.11.0 |
| Lint | golangci-lint | 2.15.0 |
| Node (Tailwind build only) | Node.js | 22 |
Versions come from the starter’s versions.json and are checked against it on every deploy; a mismatch fails the build.
Row Level Security, tested
Policies enforced in the database and integration-tested. Request JWT claims ride into every query through a scoped transaction, so the repository layer cannot skip tenant scoping (ADR-004).
A demo that proves the stack
A patterns showcase of every HTMX/Alpine pattern the starter supports, plus an architecture quiz whose wrong answers become per-user flashcards behind RLS (ADR-024).
Performance budgets in CI
Binary size, gzipped asset budgets and memory limits are enforced by task ci, not aspired to in a README (ADR-000).
Agentic discipline
The starter does not treat auth and data as pluggable adapters. The auth middleware validates Supabase JWTs and carries the claims into every database transaction, guest mode issues real anonymous Supabase identities server-side, and the TTL reaper uses the Supabase admin API. Swapping Supabase means rewriting the auth middleware, the RLS scope helper and the policies. What the lock-in buys is multi-tenancy that is proven by integration tests and exercised by the live demo.
Prerequisites: Go, Docker with Compose, Task, and Node.js for the Tailwind build.
git clone https://github.com/clownware/go-performance-starter.gitcd go-performance-startercp .env.example .env # add Supabase credentials and DATABASE_URLtask db:up # local Postgrestask db:migrate:uptask db:generate # sqlc typestask dev # hot reloadtask ci is the load-bearing quality gate: format, lint, race tests, agent-spine and versions drift checks, binary size and vulnerability scan all hang off it. Removing a gate means editing Taskfile.yml, not the workflow.