Skip to main content
skill CX Codex

go-architecture-review — Claude Code skill for Go architecture

This skill reviews Go package structure, dependency direction, and module boundaries. Use it to assess an existing codebase or plan a refactor.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add eduardo-sl/go-agent-skills --skill go-architecture-review -a claude-code
Open on GitHub

What go-architecture-review does

The skill judges architecture against the project’s needs, so a small service does not get layers just for the sake of having them. It checks package responsibilities and how dependencies cross layers. Ask for a refactor plan and it returns an ordered migration path; for a new service, it gives structural guidance instead of auditing existing code.

For large repositories, it builds a dependency map with go list ./... and import statements, then reviews package design, wiring, configuration, and dependency direction. Findings point to package paths and file lines. The skill is read-only, and it requires the Go toolchain.

It does not cover Go coding style or endpoint design; those are handled by the separate go-coding-standards and go-api-design skills.

What it helps with

  • spot circular dependencies between packages
  • check whether dependencies point inward
  • assess whether package structure fits the project
  • plan a staged refactor from a monolith into modules

Example prompts for the agent

  • Review this Go project’s architecture and cite a file and line for each finding.
  • Suggest a package layout for a new Go service with HTTP and a database.
  • Write a safe, ordered plan for splitting this monolith into modules.

How to install go-architecture-review

1Skills CLI (Vercel)

npx skills add eduardo-sl/go-agent-skills --skill go-architecture-review -a claude-code

2Manually: put the files in place

~/.claude/skills/go-architecture-review/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/go-architecture-review/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about go-architecture-review

How do I install go-architecture-review in Claude Code?

Run npx skills add eduardo-sl/go-agent-skills --skill go-architecture-review -a claude-code. The skill file is at ~/.claude/skills/go-architecture-review/SKILL.md.

What does go-architecture-review do?

It examines Go project structure, package dependencies, and layer boundaries. It can report architecture findings or produce a sequenced refactoring plan, without editing files.

Does go-architecture-review need the Go toolchain?

Yes. It requires the Go toolchain and only reads the project; it does not modify code.

Source text

SKILL.md · MIT
---
name: go-architecture-review
description: >
  Review Go project architecture: package structure, dependency direction,
  layering, separation of concerns, domain modeling, and module boundaries.
  Use when reviewing architecture, designing package layout, evaluating
  dependency graphs, or refactoring monoliths into modules. Trigger
  examples: "review architecture", "package structure", "project layout",
  "dependency direction", "clean architecture Go", "module boundaries".
  Not for: code-level style (go-coding-standards), endpoint design
  (go-api-design).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. Read-only: this skill reports findings, it does not edit code.
allowed-tools: Read Glob Grep Bash(go:*) Bash(gofmt:*)
metadata:
  author: eduardo-sl
  version: "1.3.0"
---

# Go Architecture Review

Good architecture makes the next change easy. Bad architecture makes every change scary.

Detailed reference material, loaded on demand:

- `references/layout-and-wiring.md` — the full reference directory tree and
  a composition-root `main.go`.

Read a reference file only when the summary below is not enough.

## Operating Modes

Pick the mode that matches the request before starting:

- **Layout review** (default) — assess an existing codebase against the
  sections below and report violations with severity.
- **Refactor plan** — same assessment, but the deliverable is an ordered
  migration plan (smallest safe steps first), not just findings.
- **New service consultation** — asked "how should I structure X":
  apply sections 1-3 as prescriptive guidance instead of review checks.

## Match the Architecture to the Problem

Judge a codebase against the structure its problem needs, not the most
elaborate one available. Over-architecture is a finding too.

| Situation | Fitting structure |
|---|---|
| CLI, small service, one data store, little business logic | Flat `main` + a few packages; no layers for their own sake |
| Typical service: HTTP/gRPC in front, a database behind | Handler → service → store, interfaces at the consumer (sections 1-2) |
| Several adapters (HTTP, gRPC, queue, CLI) over the same rules, or infrastructure expected to change | Ports and adapters: a pure core, adapters on the edge |
| Large domain, several teams, rules that differ by sub-domain | Bounded contexts as top-level packages, each layered inside, talking through explicit APIs or events |

Signs of too much: interfaces with one implementation per layer, mapping
structs copied unchanged through three layers, a "domain" package with no
behavior. Signs of too little: SQL in handlers, business rules spread
across transport code, packages that import each other in both directions.

## Auditing Large Codebases

For repositories with many packages, build the dependency picture before
judging it:

1. Map the module: `go list ./...` for packages, then import statements
   to trace dependency direction.
2. Run independent passes: (a) layout vs section 1, (b) dependency
   direction vs section 2, (c) wiring and config vs sections 3+5,
   (d) package design vs section 4.
3. If your environment supports delegating work to parallel sub-agents
   or tasks, assign each pass to one; synthesize at the end — dependency
   findings often explain layout findings.
4. Cite package paths and `file.go:line` in every finding.

## 1. Standard Project Layout

The reference layout: `cmd/<binary>/main.go` per binary, project-private
code under `internal/` (`domain`, `service`, `store/<backend>`,
`handler`, `config`), `pkg/` only for genuinely reusable code, plus
`api/` for OpenAPI/proto and `migrations/`. Full tree:
`references/layout-and-wiring.md`. For scaffolding a new project, the
go-project-layout skill owns the procedure.

### Key Rules:
- `internal/` enforces encapsulation at the compiler level. Use it aggressively.
- `pkg/` is for genuinely reusable packages. When in doubt, use `internal/`.
- `cmd/` main packages should be thin — wire dependencies and call `Run()`.
- One `main.go` per binary, minimal logic inside.

## 2. Dependency Direction

Dependencies MUST flow inward. Domain core has zero external dependencies:

```text
handlers → services → domain ← stores
    ↓          ↓                  ↓
  (net/http)  (pure Go)     (database/sql)
```

Rules:
- `domain/` imports NOTHING from the project. No `store`, no `handler`, no `config`.
- `service/` depends on `domain/` types and interfaces, NOT on concrete stores.
- `handler/` depends on `service/` interfaces.
- `store/` implements interfaces defined in `service/` or `domain/`.
- Circular dependencies are a 🔴 BLOCKER. The compiler catches them, but design should prevent them.

```go
// ✅ Good — service defines the interface it needs
// internal/service/user.go
type UserStore interface {
    GetByID(ctx context.Context, id string) (*domain.User, error)
    Create(ctx context.Context, user *domain.User) error
}

type UserService struct {
    store UserStore // depends on interface, not postgres.Store
}

// internal/store/postgres/user.go
type Store struct { db *sql.DB }

// Implements service.UserStore without importing the service package
func (s *Store) GetByID(ctx context.Context, id string) (*domain.User, error) { ... }
```

## 3. Main Package Wiring

`main.go` is the composition root. Wire everything here:

Read config, build the logger, open connections, construct stores →
services → handlers in that order, mount routes, run the server. No
business logic. Example: `references/layout-and-wiring.md`.

Avoid dependency injection frameworks. Go's explicit wiring is a feature.
If wiring gets complex, use Google's `wire` for compile-time DI code generation.

## 4. Package Design Principles

### One package = one purpose

```go
// ✅ Good — clear purpose
package orderservice  // business rules for orders
package postgres      // PostgreSQL data access
package httphandler   // HTTP transport layer

// ❌ Bad — grab-bag packages
package utils    // what ISN'T a util?
package common   // everything and nothing
package models   // types without behavior
```

### Avoid package stuttering

```go
// ❌ Bad — package name repeated in type
package user
type UserService struct{} // user.UserService

// ✅ Good
package user
type Service struct{} // user.Service
```

### Package cohesion over size

A package with 20 related files is better than 20 packages with 1 file each.
Split packages when they have distinct responsibilities, not when they get big.

## 5. Configuration

```go
type Config struct {
    Addr        string        `env:"ADDR" envDefault:":8080"`
    DatabaseURL string        `env:"DATABASE_URL,required"`
    LogLevel    string        `env:"LOG_LEVEL" envDefault:"info"`
    Timeout     time.Duration `env:"TIMEOUT" envDefault:"30s"`
}
```

Rules:
- All config from environment variables (12-factor).
- Validate at startup, fail fast with clear messages.
- No config scattered across packages — centralize in `internal/config`.
- Never hardcode values. Not even "just for now."

## 6. Init Functions

Avoid `init()`. It runs implicitly, makes testing harder, and creates hidden dependencies.

```go
// ❌ Bad — hidden side effects
func init() {
    db, _ = sql.Open("postgres", os.Getenv("DB_URL"))
}

// ✅ Good — explicit initialization
func NewStore(dsn string) (*Store, error) {
    db, err := sql.Open("postgres", dsn)
    if err != nil {
        return nil, fmt.Errorf("open db: %w", err)
    }
    return &Store{db: db}, nil
}
```

Exception: registering drivers or codecs is acceptable in `init()`:
```go
func init() {
    sql.Register("custom", &CustomDriver{})
}
```

## Architecture Review Checklist

- 🔴 No circular dependencies between packages
- 🔴 Domain types have zero infrastructure dependencies
- 🔴 No business logic in `cmd/` main packages
- 🔴 No `init()` with side effects (DB connections, HTTP calls)
- 🟡 `internal/` used for project-private packages
- 🟡 Interfaces defined at the consumer, not the producer
- 🟡 Configuration centralized and validated at startup
- 🟡 Dependency direction flows inward (handlers → services → domain)
- 🟢 Package names are short, singular, descriptive
- 🟢 No `utils/`, `common/`, `helpers/` packages
- 🟢 Main package is a thin composition root
- 🟢 Structure is proportional to the domain — no layers or interfaces without a second reason to exist

© eduardo-sl · MIT · eduardo-sl/go-agent-skills

Similar skills

All skills for Code review and refactoring →

From the same set34

go-openapi Enforces spec-first REST development in Go by generating servers and clients via oapi-codegen, validating requests, and detecting breaking API changes. CX Codex +1 ★ 83repo stars go-interface-design This skill guides Go interface design, package decoupling, and compile-time contract checks. Use it when shaping dependencies or refactoring code for testability. CX Codex +1 ★ 83repo stars go-grpc A skill that steers your coding agent through gRPC work in Go: proto contracts, error codes, deadlines, interceptors and streaming. CX Codex +1 ★ 83repo stars go-graphql A skill for building Go GraphQL servers with gqlgen. It guides schema-first generation, fixes N+1 query fan-outs via dataloaders, and enforces query limits. CX Codex +1 ★ 83repo stars go-design-patterns This skill helps an agent choose Go patterns for constructors, runtime behavior and dependency failures. Use it when deciding how to structure a Go project. CX Codex +1 ★ 83repo stars go-dependency-injection A skill that steers your agent toward constructor injection and a single composition root in main. Useful once globals creep in or tests get hard to write. CX Codex +1 ★ 83repo stars go-cli Guides coding agents in building well-behaved Go CLI tools with clean signal handling, flag parsing, and Unix I/O discipline. CX Codex +1 ★ 83repo stars go-api-design A skill that steers the agent through Go HTTP handler design: routing, middleware, validation, pagination, graceful shutdown. Useful when you start a REST service or rework one. CX Codex +1 ★ 83repo stars

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor