Go modular-monolith backend template with Clean Architecture — clear layer boundaries, production-ready API foundations, and agent rules that keep AI-assisted changes consistent.
- Multi-binary-ready composition — support for adding future workers as sibling process packages without duplicating runtime setup.
- HTTP safety and streaming — timeouts, graceful shutdown, CORS allowlists, trusted-proxy IP extraction, security headers, and reusable Server-Sent Events with a bounded health-stream demo.
- Authentication — Redis-backed sessions and OTPs, optional Resend email delivery, optional Google OAuth, and secure cookie defaults.
- Rate limiting — app-level Redis token-bucket per-IP limiting at the origin, useful without a CDN and as defense in depth behind one.
- Data stores — SQL-first PostgreSQL, Redis cache-aside store composition, and a ready-to-wire object-storage adapter — with vendor types kept inside infra.
- Observability — OpenTelemetry tracing and metrics, plus structured logging — kept behind app-owned interfaces.
- Testing — layered unit, adapter integration, and HTTP feature tests, with disposable PostgreSQL and Redis containers managed by Testcontainers.
- Local development — local hot reload and Docker Compose for Postgres, Redis, and observability services.
- Agent rules — AI coding guidance that encodes the template's layer boundaries and patterns.
These keep framework and infrastructure details at the edges so business logic stays independent and changes stay localized.
Architecture & structure
- Clean Architecture
- Dependency Injection (Composition root)
- SOLID principles
- Consumer-owned interfaces
Structural patterns
Behavioral & creational
Data & transport
See package-level README.md files and AGENTS.md for implementation guidance and shared architecture rules for both engineers and AI agents.
Tests protect behavior at the layer that owns it: keep the subject real, replace dependencies outside the scope, and avoid repeating lower-layer assertions in higher-level tests.
| Scope | Protects | Dependencies |
|---|---|---|
| Unit | Business rules, transport mapping, edge cases, and orchestration | Collaborators replaced with configurable test doubles |
| Adapter integration | PostgreSQL queries and Redis persistence, serialization, TTL, and atomicity | Real backend managed by Testcontainers |
| HTTP feature integration | Client-visible workflows across delivery, usecases, repositories, and infra | Real PostgreSQL/Redis; external providers replaced |
Versioned, disposable PostgreSQL and Redis instances keep integration tests reproducible across local development and CI without developer-managed services. Each package shares its containers for speed, isolates data per test, emits logs on failure, and terminates resources explicitly.
GitHub Actions runs quality/unit checks and container-backed integration tests in parallel, with dependency caching, job timeouts, failure diagnostics, and cancellation of superseded runs. Both jobs can be required by branch protection.
Transport
Echo v5- HTTP servergo-playground/validator/v10- request/DTO validation (struct tags)OpenAPI 3- source of truth for HTTP contractsoapi-codegen- backend transport model generation from OpenAPI
Database
pgx/v5- PostgreSQL driver and connection poolsqlc- static SQL query generationMasterminds/squirrel- dynamic SQL constructionpressly/goose- database migrations
Why SQL-first data access (no ORM)
- Raw SQL with
sqlc+squirrelprovides explicit query control, predictable performance tuning, and compile-time type safety. - Common downsides are handled by:
sqlcgenerated typed mappings to reduce runtime schema/query mismatch risk.squirrelcomposable dynamic SQL to avoid fragile string concatenation.- Clean Architecture + repository boundaries to isolate SQL in infra adapters and keep usecases storage-agnostic.
Cache
go-redis/v9- Redis client integration
Object storage
AWS SDK for Go v2- S3-compatible Cloudflare R2 object-storage adapter
Authentication
golang.org/x/oauth2- OAuth 2.0 client support for Google loginResend- optional OTP email delivery
Observability & logging
uber-go/zap- structured loggingOpenTelemetrySDK +OTLPexporters - tracing, logs, and metricsHyperDX+OpenTelemetry Collector- local observability integration
Testing & CI
Testcontainers for Go- disposable PostgreSQL and Redis dependencies for integration testsGitHub Actions- automated quality, unit, and integration checks
Development & infra
air- local hot reloadDocker Compose- local infrastructure orchestration
- Create a new repository from this template.
- Bootstrap the project:
./scripts/bootstrap-template.sh --module github.com/your-org/your-backendThis updates module/import paths, service and stack naming, OpenAPI title, and README title.
- If you cloned this repo directly, rename your project directory and set the Git remote to your new repository. The script does not change directory names or remotes.
- Validate with
make openapi-generate && make test. - Review
docker-compose.yml,.env.example, anddocs/openapi.yamlfor project-specific values. The auth (pluggable OTP/OAuth + session), cached user store, and health modules are production-ready foundations—extend them and add your own migrations and features. - Review
AGENTS.mdand package-levelREADME.mdfiles before feature development.
cp .env.example .envmake installmake dev-up && make migrate-upmake run- Verify
GET /health?check=ready
Common commands: make dev-logs, make dev-down, make migrate-status, make openapi-generate, make run-stop.
Default local ports: Postgres 5432, Redis 6379, OTel 4317/4318, HyperDX 8081.
Run the checks most relevant to your change:
make check
make test
make test-race
make test-integrationDocker must be running for make test-integration; the test suites create and remove their own PostgreSQL and Redis containers. No database or Redis environment variables are required.
Run the same complete sequence used by CI:
make ciTo observe the bounded SSE demo while the API is running:
curl -N 'http://localhost:8080/health/stream?check=ready'