A Go web app template.
Modern web development is buried under layers of tooling, transpilers, bundlers, ORMs, and frameworks that do too much. Stoic takes a different approach, and minimizes what's between you and your code.
Stoic boot straps your project with OIDC auth, a Postgres data store, server-rendered HTML templates, and Server-Sent-Events (SSE) to pushed data to clients. Wired together in ~1200 lines of code you own. No framework. No magic. Clone it, rename it, and build on it.
- Compile-time safety. A wrong type, a missing field, an unused import — caught before the code runs.
- One goroutine per request. Sequential code that handles concurrency.
- Single binary deployment.
go buildproduces one file with zero dependencies. - Predictable performance. Sub-millisecond GC pauses. Tens of thousands of concurrent connections on modest hardware.
- Stdlib does the work.
net/httpis a production server, not a dev placeholder.crypto,encoding/json,html/template— battle-tested, no third-party replacements needed. - Fast cold starts, small footprint. Starts in milliseconds, idles at 10-30MB. Your containers stay light and your cloud bill stays low.
- ~1200 lines of glue code over well-known Go libraries (gorilla/mux, pgx, go-oidc, SQLC). The value is in the wiring decisions, not abstraction.
- "Opinionated" and "library" are in tension — adding interfaces for pluggability undoes the opinions.
- Go developers prefer to own their code. You can read and modify 249 lines of auth code. That's a feature.
- No semver, no backwards compatibility, no API docs to maintain. Just code you control.
- OIDC authentication (Keycloak, Auth0, Okta, or any provider)
- Postgres with auto-migrations and type-safe queries (SQLC)
- Server-rendered HTML templates with hot-reload in dev
- Server-Sent Events for real-time updates
- Session management with automatic token refresh
- Centralized config loaded once at startup
-
Clone this template:
gh repo create my-project --template antonkarounis/stoic
-
Rename the module:
make rename
-
Start dev services (Postgres + pgAdmin + Keycloak):
make dev-start
-
Copy over the config (has a working example configs):
cp .env.example .env
-
Run:
make run
-
Log in with
[email protected]andpassword
internal/platform/ — Framework plumbing (auth, db, templates). Rarely modified.
internal/app/ — Your application code. Start here.
routes.go — Register your routes
handlers/ — Your request handlers
templates/ — Your HTML templates
migrations/ — Your database migrations
- Create a handler in
internal/app/handlers/ - Create a template in
internal/app/templates/www/ - Register the route in
internal/app/routes.go - Done.
- Write a migration in
internal/app/migrations/ - Write queries in
internal/platform/db/queries/ - Run
make sqlcto regenerate - Use the generated functions in your handlers