Skip to content
Development
Skill

/go-clean-architecture

Use when scaffolding or refactoring a Go service into a framework-agnostic clean (hexagonal) architecture: Domain, Usecase, Repository, Delivery layers, inward dependency rule, 'framework/database is a detail'. Apply when untangling a monolith or checking whether business logic

From plugin
gophers
926 skills4 agents

Claude Code

$ npx -y skills add muratmirgun/gophers --skill go-clean-architecture --agent claude-code

SKILL.md

go-clean-architecture.SKILL.md
name: go-clean-architecture
description: "Use when scaffolding or refactoring a Go service into a framework-agnostic clean (hexagonal) architecture: Domain, Usecase, Repository, Delivery layers, inward dependency rule, 'framework/database is a detail'. Apply when untangling a monolith or checking whether business logic is testable without HTTP or DB."
license: MIT
compatibility: "Designed for Claude Code or similar AI coding agents. Requires Go 1.21+. Framework-agnostic: works with Gin, Echo, Fiber, Chi, or net/http; swap freely."
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*)

Go Clean Architecture

A Go service organized into four concentric layers — Domain, Usecase, Repository, Delivery — where source code depends *inward only*. Done well, the HTTP framework and the database are interchangeable details; the business logic is testable without either.

This skill is framework-agnostic. Swap Gin for Fiber, Echo, Chi, or `net/http` by replacing the delivery layer — zero changes elsewhere.

Core Rules

1. **Dependency Rule.** Source depends inward: Delivery → Usecase → Domain. Repository implements interfaces declared in Domain. Domain depends on nothing. 2. **Framework is a detail.** Gin/Fiber/Echo/Chi/net-http types live only in `internal/delivery/`. Usecases see plain Go values. 3. **Database is a detail.** SQL, sqlx, sqlc, pgx, GORM live only in `internal/repository/`. Usecases see repository interfaces. 4. **Domain owns the interfaces; layers below provide implementations.** `UserRepository` is an interface in `internal/domain`; the Postgres struct is in `internal/repository` and unexported. 5. **DTOs at the edges.** Delivery layer maps HTTP request bodies to domain inputs and domain entities to response bodies. Usecases never see `*gin.Context`, `http.Request`, or DB rows. 6. **`cmd/<binary>/main.go` is the only place that knows the whole system.** Wiring (DI) is explicit, framework-free Go code.

When This Pays Off

| Symptom | What clean architecture buys you | |---|---| | HTTP handlers contain SQL | Move SQL into a repository; handlers shrink to 5 lines | | Tests need a running DB | Mock the repository interface; usecase tests run in milliseconds | | Swapping web frameworks is a rewrite | Replace `internal/delivery/http`; nothing else touched | | Business rules duplicated across handlers | Single usecase function, called by HTTP, gRPC, and a CLI | | ORM hooks fire in surprising places | Repository methods are explicit; no hidden behavior |

If the service is a 200-line cron job, this skill is overkill. If it will live 3+ years and grow features, it's the cheapest insurance you can buy.

Project Structure

myapp/
  cmd/
    api/main.go             # entry point: config → DI → start server
    worker/main.go          # different entry, same Domain & Usecase
  internal/
    domain/                 # entities, value objects, repository INTERFACES, domain errors
      user.go
      order.go
      errors.go
    usecase/                # business logic; depends only on domain
      user_usecase.go
      order_usecase.go
    repository/             # implementations of domain interfaces (Postgres, in-memory, ...)
      user_postgres.go
      order_postgres.go
    delivery/               # framework-specific adapters
      http/                 # Gin/Echo/Chi/net-http handlers and routes
        user_handler.go
        order_handler.go
      grpc/                 # gRPC server adapters (if applicable)
  pkg/                      # exported, importable from outside (if you publish a library)
  migrations/               # SQL migrations
  config/
  go.mod

> Read [references/domain.md](references/domain.md), [references/usecase.md](references/usecase.md), [references/repository.md](references/repository.md), and [references/delivery.md](references/delivery.md) for the per-layer responsibilities.

The Four Layers

| Layer | Package | Can import | Must not import | |---|---|---|---| | Domain | `internal/domain` | stdlib only | usecase, repository, delivery, frameworks | | Usecase | `internal/usecase` | domain | repository (concrete), delivery, frameworks | | Repository | `internal/repository` | domain, DB driver | delivery, frameworks | | Delivery | `internal/delivery/...` | domain, usecase (via interface), framework | repository (concrete) |

A `golangci-lint` config with `depguard` enforces these rules at CI time.

Layer Sketches

// Domain — pure interfaces and entities, no I/O.
package domain
type User struct { ID, Email, Name string; CreatedAt time.Time }
type UserRepository interface {
    Get(ctx context.Context, id string) (*User, error)
    Create(ctx context.Context, u *User) error
}
type UserService interface {
    Create(ctx context.Context, in CreateUserInput) (*User, error)
}
// Usecase — business logic, depends only on domain interfaces.
type userUsecase struct{ repo domain.UserRepository }

func NewUserUsecase(repo domain.UserRepository) domain.UserService {
    return &userUsecase{repo: repo}
}
// Repository — concrete adapter, translates driver errors to domain errors.
type postgresUserRepo struct{ db *sql.DB }
func NewUserRepository(db *sql.DB) domain.UserRepository { return &postgresUserRepo{db: db} }
// Delivery — HTTP framework lives only here; swap freely.
type UserHandler struct{ svc domain.UserService }
func NewUserHandler(svc domain.UserService) *UserHandler { return &UserHandler{svc: svc} }

> Read [references/domain.md](references/domain.md), [references/usecase.md](references/usecase.md), [references/repository.md](references/repository.md), and [references/delivery.md](references/delivery.md) for full code examples per layer.

Wiring in `main.go`

// cmd/api/main.go — the only place that knows the whole system.
db, _ := sql.Open("postgres", cfg.DBURL)
userRepo := repository.NewUserRepository(db)
userSvc  := usecase.NewUserUsecase(userRepo)
userH    := de
Read more
@muratmirgun
Ships withgophers

26 production-grade Go skills for Claude Code, Gemini CLI, and opencode. Battle-tested patterns from the Go community — codified as triggerable AI skills.

926 skills4 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
9
Star history of muratmirgun/gophers on GitHub, a chart by star-history.com

Other skills on gophers.

go-code-review

go-code-review

Invoke this skill to systematically review a Go change against community style standards before merging. Walks the diff topic by…

@muratmirgun@muratmirgunInstall Skill
go-code-style

go-code-style

Use when writing or reviewing Go code for clarity, formatting, control flow, variable declarations, switch usage, and function…

@muratmirgun@muratmirgunInstall Skill
go-concurrency

go-concurrency

Use when writing or reviewing concurrent Go code — goroutines, channels, select, mutexes, atomics, errgroup, singleflight, worker…

@muratmirgun@muratmirgunInstall Skill
go-context

go-context

Use when designing, propagating, or debugging context.Context flow in Go — first-parameter placement, deadlines and cancellation,…

@muratmirgun@muratmirgunInstall Skill
go-control-flow

go-control-flow

Use when writing conditionals, loops, switches, type switches, or blank-identifier patterns in Go. Covers if-with-initialization,…

@muratmirgun@muratmirgunInstall Skill
go-data-structures

go-data-structures

Use when choosing or operating on Go slices, maps, arrays, strings, or container/* types — including slice internals, capacity…

@muratmirgun@muratmirgunInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc13d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about go-clean-architecture.

Which coding agents can use go-clean-architecture?
go-clean-architecture installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.