{"id":50366771,"url":"https://github.com/emilioforrer/go-stack","last_synced_at":"2026-05-30T04:30:38.897Z","repository":{"id":355288781,"uuid":"1158234058","full_name":"emilioforrer/go-stack","owner":"emilioforrer","description":"Production-ready Go scaffold template with clean architecture, lifecycle-managed dependency injection (samber/do), HTTP server (net/http + Huma/OpenAPI), CLI scaffolding, 45+ AI agent skills for Claude/Copilot/OpenCode, and built-in DevOps security tooling.","archived":false,"fork":false,"pushed_at":"2026-05-09T05:40:19.000Z","size":1348,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T04:30:34.452Z","etag":null,"topics":["agentic-coding","ai-agent","ai-skills","claude","clean-architecture","cli","code-quality","codex","copilot","dependency-injection","go","golang","microservices","openapi","opencode","production-ready","security","starter-kit","template","vertical-slice-architecture"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emilioforrer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-15T02:24:59.000Z","updated_at":"2026-05-28T23:42:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/emilioforrer/go-stack","commit_stats":null,"previous_names":["emilioforrer/go-stack"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/emilioforrer/go-stack","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilioforrer%2Fgo-stack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilioforrer%2Fgo-stack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilioforrer%2Fgo-stack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilioforrer%2Fgo-stack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emilioforrer","download_url":"https://codeload.github.com/emilioforrer/go-stack/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilioforrer%2Fgo-stack/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33680522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-coding","ai-agent","ai-skills","claude","clean-architecture","cli","code-quality","codex","copilot","dependency-injection","go","golang","microservices","openapi","opencode","production-ready","security","starter-kit","template","vertical-slice-architecture"],"created_at":"2026-05-30T04:30:38.166Z","updated_at":"2026-05-30T04:30:38.885Z","avatar_url":"https://github.com/emilioforrer.png","language":"Go","funding_links":["https://ko-fi.com/emilioforrer"],"categories":[],"sub_categories":[],"readme":"# go-stack\n\n[![Ko-fi](https://img.shields.io/badge/Ko--fi-Support%20me-ff5f5f?logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/emilioforrer)\n\n**go-stack** is a scaffold template for Go projects designed to help you kickstart production-ready applications with confidence. It follows Go best practices, enforces clean architecture, and provides a well-organized structure that is easy to extend and maintain.\n\nThis template is built with the following principles in mind:\n- **Best Practices** — idiomatic Go, standard project layout, and consistent conventions.\n- **Clean Architecture** — clear separation of concerns with modular, testable layers.\n- **AI Agentic Ready** — structured, documented, and predictable code that automated agents and LLMs can understand and extend with ease.\n- **Easy to Extend** — pluggable packages, dependency injection, and minimal coupling so new features fit in naturally.\n\n## Installation\n\nInstall the CLI globally using `go install`:\n\n```bash\ngo install github.com/emilioforrer/go-stack/cmd/go-stack@latest\n```\n\n## CLI\n\nThe `go-stack` CLI helps you scaffold new projects from this template in seconds.\n\n### Commands\n\n| Command | Description | Example |\n|---|---|---|\n| `new \u003cpath\u003e` | Create a new project from the template at the given path. | `go-stack new ./my-app` |\n\n### Flags for `new`\n\n| Flag | Description | Default |\n|---|---|---|\n| `--name` | Project name (used for Sonar properties). | inferred from path |\n| `--module` | Go module name for the generated project. | inferred from path |\n\n## Project Structure\n\nRunning `go-stack new ./my-app` generates a scaffold with a purpose-built layout optimized for the `boot` + `httpsvr` ecosystem:\n\n```\nmy-app/\n├── cmd/\n│   └── app/                  # CLI entry point (Cobra commands)\n│       ├── main.go          # Application entry point\n│       ├── root.go          # Root command definition\n│       ├── serve.go         # HTTP server command\n│       ├── version.go       # Version command\n│       ├── completion.go    # Shell completion command\n│       └── exit_code.go     # Exit code utilities\n├── boot/\n│   └── provider/            # Boot providers (server, DB, cache, queue, etc.)\n│       └── server.go        # HTTP server provider (includes Huma + OpenAPI)\n├── devops/\n│   └── security/            # Security scan results, SBOM, Docker Compose, etc.\n├── .agents/\n│   └── skills/              # Codex skills (45+ Go best-practice files)\n├── .claude/\n│   └── skills/              # Claude Code skills (45+ Go best-practice files)\n├── .gemini/\n│   └── skills/              # Gemini skills (45+ Go best-practice files)\n├── .github/\n│   └── skills/              # GitHub Copilot skills (45+ Go best-practice files)\n├── .opencode/\n│   └── skills/              # OpenCode agent skills (45+ Go best-practice files)\n├── .air.toml                # Live reload configuration\n├── .golangci.yml            # Linter configuration\n├── .goreleaser.yml          # Release automation\n├── .mise.toml               # Development environment tooling\n├── Taskfile.yml             # Task runner configuration\n├── apm.yml                  # APM (Agent Package Manager) configuration\n├── apm.lock.yaml            # APM lock file\n└── go.mod                   # Module definition\n```\n\n### AI Agent Package Manager (APM)\n\nThis template is **AI agentic ready**. It ships with contextual skill files for three major agent platforms:\n\n| Directory | Agent |\n|---|---|\n| `.agents/skills/` | AI Agents (Codex) |\n| `.claude/skills/` | Claude Code |\n| `.gemini/skills/` | Gemini |\n| `.github/skills/` | GitHub Copilot |\n| `.opencode/skills/` | OpenCode |\n\nEach directory contains **45+ skill files** covering the entire Go ecosystem — concurrency, error handling, testing, security, database patterns, design patterns, Cobra, Viper, samber/do, samber/lo, gRPC, GraphQL, and more. When an AI agent works inside the repository, it automatically loads these skills, ensuring it follows the project's best practices and generates idiomatic, well-structured code.\n\n## Packages\n\nA collection of reusable Go packages for building well-structured applications.\n\nEach package lives under `pkg/` as an independent Go module that can be imported individually.\n\n| Package | Description | Install |\n|---|---|---|\n| [boot](pkg/boot/README.md) | Application bootstrapping and lifecycle management built on top of [samber/do](https://github.com/samber/do) dependency injection. | `go get github.com/emilioforrer/go-stack/pkg/boot` |\n| [httpsvr](pkg/httpsvr/README.md) | HTTP server package built on `net/http` with structured router, configurable server, middleware chaining, and JSON error responses. | `go get github.com/emilioforrer/go-stack/pkg/httpsvr` |\n| [inertia](pkg/inertia/README.md) | Boot-ready Inertia.js integration with embedded assets, Vite dev server, optional SSR, and GoNertia adapter. | `go get github.com/emilioforrer/go-stack/pkg/inertia` |\n\n### boot — Lifecycle \u0026 Dependency Injection\n\n`boot` is the heart of the template. It manages application startup and teardown through a strict, deterministic lifecycle powered by [samber/do](https://github.com/samber/do).\n\n#### Core Lifecycle\n\n1. **Register** — each provider binds its services into the shared DI container.\n2. **Boot** — each provider resolves dependencies and initializes state. **Boot should NOT be a long blocking operation.** If a provider needs to do long-running work (e.g., start a background worker), launch a goroutine inside `Boot` and use a channel or `sync.WaitGroup` to signal readiness.\n3. **Shutdown** — each provider tears down gracefully in **reverse** registration order.\n\nAll phases are **idempotent**; calling them multiple times is a safe no-op.\n\n#### Key Types\n\n| Type | Role |\n|---|---|\n| `Container` | Wraps `do.Injector`; the shared service locator. |\n| `Provider` | Interface with `Register`, `Boot`, and `Shutdown` hooks. |\n| `DefaultProvider` | Embeddable no-op base — override only what you need. |\n| `DefaultBootstrapper` | Orchestrates the full lifecycle across all providers. |\n\n#### Creating a Custom Provider\n\nImplement the `Provider` interface (or embed `DefaultProvider`) and register services via `do.Provide`:\n\n```go\ntype DatabaseProvider struct {\n    boot.DefaultProvider\n}\n\nfunc (p *DatabaseProvider) Register(_ context.Context, c boot.Container) error {\n    do.Provide(c.Injector(), func(i do.Injector) (*sql.DB, error) {\n        return sql.Open(\"postgres\", dsn)\n    })\n    return nil\n}\n\nfunc (p *DatabaseProvider) Boot(_ context.Context, c boot.Container) error {\n    db, err := do.Invoke[*sql.DB](c.Injector())\n    if err != nil {\n        return err\n    }\n    return db.Ping()\n}\n\nfunc (p *DatabaseProvider) Shutdown(_ context.Context, c boot.Container) error {\n    db, _ := do.Invoke[*sql.DB](c.Injector())\n    return db.Close()\n}\n```\n\nThen wire it into the bootstrapper in `main`:\n\n```go\nb := boot.NewDefaultBootstrapper(do.New(), \u0026DatabaseProvider{}, \u0026httpsvr.Provider{})\n_ = b.Register(ctx)\n_ = b.Boot(ctx)\n// ... application runs ...\n_ = b.Shutdown(ctx)\n```\n\nBecause providers are registered in order, you can safely depend on earlier providers during `Boot`. Because `Shutdown` runs in reverse, services that depend on the database will be stopped before the database itself is closed.\n\n### httpsvr — Production-Ready HTTP Server\n\n`httpsvr` provides a thin, opinionated layer over `net/http` that includes routing, middleware chaining, graceful shutdown, and standardized JSON error responses.\n\n#### Key Types\n\n| Type | Role |\n|---|---|\n| `DefaultRouter` | `http.ServeMux`-backed router with per-route middleware. |\n| `DefaultHTTPServer` | Standard `net/http.Server` with configurable timeouts. |\n| `DefaultApp` | Full lifecycle app with OS signal handling and graceful shutdown. |\n| `Middleware` | `func(http.Handler) http.Handler` — composable by design. |\n\n#### Built-in Middleware\n\n| Middleware | Purpose |\n|---|---|\n| `RequestLoggerMiddleware` | Rails-style request logging with status and duration. |\n| `RecoveryMiddleware` | Recovers from panics and returns 500. |\n| `TracingMiddleware` | Injects a trace ID into the request context. |\n| `NotFoundMiddleware` | JSON 404 responses for unmatched routes. |\n| `InternalServerErrorMiddleware` | JSON 5xx responses. |\n| `ClientErrorMiddleware` | JSON 4xx responses (excluding 404). |\n\nYou can mount the router as a `boot.Provider` so the server starts and stops automatically with the rest of your application lifecycle.\n\n### Optional Huma Integration\n\nThe scaffold comes with [Huma](https://huma.rocks/) wired into the HTTP server provider (`boot/provider/server.go`). Huma provides automatic OpenAPI 3.x generation, request/response validation, and structured JSON error handling — all on top of the standard library `net/http`.\n\n\u003e **Huma is completely optional.** If you prefer a different API framework or plain `net/http`, you can remove the Huma adapter and its dependency from `go.mod` without affecting the rest of the `boot` or `httpsvr` packages.\n\n## Extending the Project\n\nTo add a new feature (e.g., a cache, a message queue, or a third-party client):\n\n1. **Create a provider** in a new package or inside `internal/`.\n2. **Implement `Register`** to bind the service into the `do.Injector`.\n3. **Implement `Boot`** to validate configuration or warm up connections.\n4. **Implement `Shutdown`** to release resources cleanly.\n5. **Add the provider** to `NewDefaultBootstrapper(...)` in `cmd/\u003capp\u003e/main.go`.\n\nBecause every provider shares the same `Container`, cross-service dependencies are resolved automatically by `samber/do`. This keeps `main` small, makes unit testing trivial, and guarantees a deterministic startup/shutdown sequence.\n\n## DevOps, Security \u0026 Code Quality\n\nThe template is **DevOps-ready** out of the box. It ships with local infrastructure and security scanning baked into the scaffold:\n\n| Capability | What it does |\n|---|---|\n| Dockerized SonarQube | A ready-to-run `docker-compose.yml` under `devops/security/` spins up a local SonarQube server for continuous code quality inspection. |\n| SonarQube Scanner | Configured to scan the project against the local (or remote) SonarQube instance and publish reports. |\n| Trivy | Lightweight vulnerability scanner for container images, filesystem, and repositories. |\n| Grype | Anchore-powered vulnerability scanner focused on SBOM (Software Bill of Materials) analysis. |\n| Snyk | Developer-first security scanner that finds and fixes vulnerabilities in dependencies and containers. |\n| SonarQube Issue Extraction CLI | A dedicated CLI tool included in `devops/security/` to fetch and export SonarQube issues for reporting or further processing. |\n\n## Tools\n\n| Tool | Description |\n|---|---|\n| [golangci-lint](https://github.com/golangci/golangci-lint) | Fast Go linters runner. |\n| [Task](https://taskfile.dev) | Task runner used to manage all project commands via `Taskfile.yml`. |\n\n### Available Task Commands\n\nThe template uses [Task](https://taskfile.dev) as its command runner. After scaffolding, run any of the following from the project root:\n\n```bash\ntask ci                    # Run CI pipeline (linter, test, coverage, release)\ntask govet                 # Run go vet\ntask linter                # Run linters\ntask release               # Run goreleaser\ntask test                  # Run tests\ntask apm:compile           # Compile APM packages\ntask apm:install           # Install APM packages\ntask mod:rename            # Rename the module in go.mod\ntask mod:replace:add       # Add local replace directives back to go.mod\ntask mod:replace:drop      # Drop local replace directives from go.mod\ntask mod:update:go:*       # Update go.mod go version\ntask release:snapshot      # Run goreleaser snapshot (no publish)\ntask run:local:serve       # Run the application locally with the serve subcommand\ntask security:grype        # Scan the project for vulnerabilities with Grype\ntask security:scan         # Run all security scans (Trivy, Grype, Snyk)\ntask security:snyk         # Scan the project for vulnerabilities with Snyk\ntask security:trivy        # Scan the project for vulnerabilities with Trivy\ntask sonarqube:scan        # Run SonarQube scanner\ntask sonarqube:start       # Start SonarQube server\ntask sonarqube:stop        # Stop SonarQube server\ntask test:coverage         # Run tests with coverage\ntask test:report           # Run tests with JSON output\n```\n\n## Roadmap\n\n- [ ] **Bun ORM integration** — Add [Bun](https://bun.uptrace.dev/) as an optional `boot` provider and standalone `pkg`, including a CLI command to run migrations. Provide a `testcontainers` helper for bootstrapping integration tests with a real database.\n- [ ] **`pkg/health` package** — Introduce a health-check provider and HTTP endpoints (`/health`, `/ready`) that aggregate the status of all registered providers.\n- [ ] **Reusable middleware package** — Add new middlewares into a dedicated `pkg/middlewares` library so they can be reused with any `net/http` compatible router.\n- [ ] **Docker \u0026 container registry integration** — Add a `Dockerfile`, `docker-compose.yml`, and Task commands to build, tag, and push the application image to a container registry.\n- [ ] **Documentation improvements** — Expand documentation with practical guides on:\n  - How to leverage the dependency injection system (samber/do) for wiring services, testing, and mocking.\n  - How to structure features using **clean architecture vertical slices** — organizing code by feature rather than by layer, keeping handlers, services, and repositories colocated.\n  - A proposed reference architecture for implementing new features (e.g., user management, payments) that demonstrates the full lifecycle from provider registration to HTTP endpoint.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femilioforrer%2Fgo-stack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femilioforrer%2Fgo-stack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femilioforrer%2Fgo-stack/lists"}