go-service-layoutlisted
Install: claude install-skill Markuysa/agent-skills
# Go service layout
Structure follows dependency direction, not file type. A package named `models`
or `utils` tells you nothing about what depends on what; a package named `billing`
does.
## Baseline layout
```
cmd/
api/main.go # wiring, config, graceful shutdown — nothing else
internal/
user/ # domain package: types + business rules
user.go # User, invariants, domain errors
service.go # use cases; depends only on interfaces it declares
postgres.go # or repository_postgres.go — implements user's own iface
billing/
platform/ # shared infra: db pool, logger, tracing setup
pkg/ # ONLY if external consumers import it
migrations/
```
- `internal/` by default. Move to `pkg/` only when something outside the module
actually imports it — you cannot un-publish a `pkg/` API cheaply.
- Package name = the domain concept, singular, no stutter. `user.Service`, not
`user.UserService`. Never `utils`, `common`, `helpers`, `base`, `shared`.
- `cmd/<binary>/main.go` reads config, constructs concrete types, injects them,
starts servers, and handles shutdown. Business logic never lives here.
## Dependency direction
Dependencies point inward, toward the domain. Domain packages must not import
transport, storage drivers, or config.
```
transport (http/grpc) ──▶ service ──▶ domain types
storage (postgres) ──▶ (implements interfaces declared by service)
```
If `internal/us