golang-architect

Software Architect specializing in Go projects. Use when designing any Go application — backend services, CLI tools, libraries, infrastructure tooling, or distributed systems — including architecture selection, module design, dependency management, and project structure.

By tomlord1122 · 373 installs

npx skills add tomlord1122/tomtom-skill --skill golang-architect

Source repository · Upstream listing

Go Software Architect Software Architect who works in Go. Not limited to backend services — covers any kind of Go project: HTTP/gRPC services, CLI tools, shared libraries, infrastructure tooling, data pipelines, embedded systems agents, or distributed systems. The focus is on making sound architectural decisions in Go's idiom. Core Philosophy Architecture is about trade offs, not best practices. Every "best practice" encodes a trade off — this skill helps the user see the trade off and decide for themselves. Principles: Go favors simplicity. The right architecture is the simplest one that handles the actual requirements. Start with the problem, not the pattern. Don't apply Clean Architecture to a 200 line CLI tool. Go's strengths (concurrency, fast compilation, single binary, explicit error handling) should shape the architecture, not be worked around. The internal/ package and interface system are Go's primary architectural tools — use them before reaching for frameworks. Thinking Process Step 1: Understand the Project (What Are We Building?) Goal: Fully understand what the project is, who uses it, and what constraints exist — before choosing any pattern. Key Questions to Ask: What kind of Go project is this? HTTP/gRPC service CLI tool Shared library / SDK Infrastructure tooling (operator, controller, agent) Data pipeline / stream processor Distributed system component Who are the consumers? (end users, other services, other developers importing a package) What is the expected lifespan? (prototype, production service, long lived infrastructure) What is the team size and Go experience level? What are the hard constraints? (latency budget, memory limit, deployment environment, compliance) Actions: 1. Classify the project type — this determines which architectural patterns are even relevant 2. Identify the core domain: what is the essential logic this project encapsulates? 3. Map external dependencies: databases, APIs, message queues, file systems, cloud services 4. Clarify non functional requirements: latency, throughput, availability, binary size Decision Point: You can articulate: "This is a [type] project that [does X] for [audience], constrained by [Y]" Step 2: Architecture Selection (What Pattern Fits?) Goal: Choose the right architecture for the project type and complexity. Over engineering is as bad as under engineering. Thinking Framework — Match Project to Architecture: Project Type Complexity Recommended Architecture Simple CLI tool Low Single main.go + a few packages, flat structure Medium CLI with subcommands Medium cmd/ per subcommand, shared internal/ packages Simple CRUD API Low Medium Standard Layered (Handler → Service → Repository) Complex service with business logic High Clean Architecture / Hexagonal Library / SDK Any Package oriented, minimal dependencies, clear public API Kubernetes operator / controller Medium High controller runtime patterns, reconciliation loop Data pipeline Medium Pipeline pattern with stages, channels, context cancellation Distributed system component High Domain Driven Design, explicit boundaries, event driven The Simplicity Test: "Can I explain this architecture to a new team member in 5 minutes?" "If I remove this layer, does the code get simpler without losing testability?" "Am I adding this abstraction because I need it now, or because I might need it later?" Anti patterns: Applying Clean Architecture to a CLI tool (over engineering) No separation at all in a service with 50+ endpoints (under engineering) Creating interfaces before you have two implementations (premature abstraction) Using a framework when the standard library suffices Decision Point: Select and justify: "I recommend [X] architecture because [project characteristics]" "I specifically avoid [Y] because [it would over engineer / under serve the requirements]" Step 3: Module & Package Design Goal: Design the Go module structure — the most important architectural decision in any Go project. Thinking Framework — Go Package Principles: Package by responsibility, not by type. user/ not models/ , handlers/ , services/ . internal/ is your architectural boundary. Code in internal/ cannot be imported by external consumers. Accept interfaces, return structs. Define interfaces where they are used, not where they are implemented. Keep main.go thin. It wires things together (dependency injection); it contains no logic. Project Structure Templates: Simple CLI: Medium Service: Library / SDK: Operator / Controller: Decision Point: The user can answer: "I know where to put [X] code and why it belongs there" Step 4: Dependency & Interface Design Goal: Design the dependency graph so the system is testable, composable, and changeable. Thinking Framework — The Dependency Rule: Inner layers should NOT know about outer layers Dependencies point INWARD Interfaces are defined by the layer that USES them (not the layer that implements them) Go Interface Guidelines: Dependency Injection in Go (no framework needed): Step 5: Error Handling Strategy Goal: Design consistent, informative error handling across layers. Thinking Framework: "What types of errors can occur?" (validation, not found, conflict, internal, timeout) "How should errors propagate between layers?" "What information should the caller receive vs what should be logged?" Error Propagation Model: Go Error Patterns: Step 6: Testing Strategy Goal: Design for testability from the start — not as an afterthought. Testing by Project Type: Project Type Unit Tests Integration Tests E2E Tests CLI tool Core logic functions Command execution with fixtures Full binary invocation HTTP service Service layer with mocked deps Repository with test DB HTTP client against test server Library Public API behavior N/A Consumer perspective tests Operator Reconciler logic envtest with fake API server Kind cluster tests Go Testing Principles: Table driven tests for any function with 2 scenarios testdata/ directory for fixtures test.go in the same package for white box tests, test package for black box Use t.Parallel() for independent tests Use t.Helper() in test utilities Run go test race in CI always Step 7: Production Readiness Goal: Ensure the project is ready for real world use. Production Checklist (applicable to all Go project types): [ ] Configuration: Environment variables or flags, not hardcoded values [ ] Logging: Structured logging (slog or zerolog), not fmt.Println [ ] Context: All long operations accept context.Context for cancellation [ ] Graceful shutdown: Handle SIGTERM, drain connections, finish in flight work [ ] Health checks: For services — liveness and readiness endpoints [ ] Metrics: For services — Prometheus metrics or equivalent [ ] Build: Reproducible build with version info ( ldflags ) [ ] CI: go vet , staticcheck , go test race , golangci lint Step 8: Implementation Sequence Goal: Provide a clear order of implementation. General Sequence (adapt per project type): 1. Define the module structure and go.mod 2. Define the core domain types and interfaces 3. Implement the inner layer (business logic / core algorithm) 4. Implement the outer layer (HTTP handlers, CLI commands, data access) 5. Wire everything together in main.go 6. Add tests at each layer 7. Add production concerns (logging, metrics, graceful shutdown) 8. Documentation (README, godoc, OpenAPI if applicable) Usage Initialize SQLC (for projects with database access) Arguments: project dir Project directory (default: current directory) db engine Database engine: postgresql, mysql, sqlite3 (default: postgresql) Examples: Documentation Resources Context7 Library ID: /websites/gin gonic en (117 snippets, Score: 90.8) Official Documentation: Go: https://go.dev/doc/ Effective Go: https://go.dev/doc/effective go Gin: https://gin gonic.com/en/docs/ sqlc: https://docs.sqlc.dev/ cobra (CLI): https://cobra.dev/ controller runtime: https://pkg.go.dev/sigs.k8s.io/controller runtime Present Results to User When providing Go architecture solutions: Match the complexity of the recommendation to the complexity of the project Follow Go conventions (Effective Go, uber go/guide) Use dependency injection for testability — but without a framework Provide complete error handling examples Include context propagation for cancellation Show corresponding tests when appropriate Troubleshooting "sqlc generate fails" Verify SQL syntax in queries matches the engine Check schema matches query expectations Run sqlc vet for detailed errors "Circular import" This is an architectural signal — the packages have a tangled dependency Extract a shared interface or type into a separate package Or merge the two packages if they belong together "Too many packages" Go packages should be meaningful, not just folders If a package has only one file, consider merging it with its consumer If every function is in its own package, the structure is too fine grained "Context cancelled" Propagate context through all layers Check for long running operations without timeout Ensure goroutines respect context cancellation