go-project-layout — скилл для Claude Code: структура Go-проекта
Подсказывает, как разложить новый Go-проект по папкам: cmd/, internal/, плоская раскладка для мелких утилит. Пригодится в самом начале, когда структура ещё не сложилась.
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a claude-codeЧто делает go-project-layout
Скилл выбирает раскладку по размеру проекта. Утилита на один бинарник и меньше пяти файлов живёт в корне в пакете main. Сервис получает cmd/<name>/main.go и пакеты под internal/. Библиотека — корневой пакет с именем модуля и internal/ для внутренностей. Пустые pkg/, api/, docs/ «на будущее» создавать не советует.
Внутри — правила именования модуля (go mod init github.com/acme/payment-service), тонкий main.go, который только парсит аргументы и вызывает run, и направление зависимостей: handler → service → domain ← store. Пакеты называются по тому, что дают, а не util или common. Конфиг грузится в одном месте и валидируется на старте.
Для работы нужен тулчейн Go и git — без него не инициализировать репозиторий. Скилл не разбирает уже существующую архитектуру, не занимается внедрением зависимостей и не настраивает CI: для этого в том же наборе есть отдельные скиллы. Если в проекте есть своё правило раскладки, оно перебивает это.
Какие задачи решает
- разложить новый Go-сервис по папкам без копирования чужого скелета
- решить, когда хватит плоской раскладки в корне
- вынести внутренние пакеты под
internal/, чтобы их не импортировали снаружи - сделать
main.goтонким и тестируемым черезrun - задать имя модуля так, чтобы он нормально фетчился
Примеры запросов агенту
- Создай скелет нового Go-сервиса:
cmd/payment-api/main.goи пакеты подinternal/ - Мне нужна структура папок для небольшой Go-утилиты на один бинарник — предложи раскладку
- Инициализируй модуль
github.com/acme/payment-serviceи напиши тонкийmain.goс вызовомrun
Как установить go-project-layout
1Через Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a claude-code2Вручную: положить файлы
~/.claude/skills/go-project-layout/SKILL.mdПапка скилла целиком; для одного проекта — .claude/skills/go-project-layout/
1Через Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a codex2Вручную: положить файлы
.agents/skills/go-project-layout/SKILL.mdДля всех проектов — ~/.agents/skills/
1Через Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a cursor2Вручную: положить файлы
.cursor/skills/go-project-layout/SKILL.mdCursor читает и .agents/skills/, и .claude/skills/
1GitHub CLI
gh skill install eduardo-sl/go-agent-skills go-project-layout2Вручную: положить файлы
.github/skills/go-project-layout/SKILL.md1Через Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a gemini-cli2Командой платформы
gemini skills install https://github.com/eduardo-sl/go-agent-skills --path 'skills/(architecture)/go-project-layout'Вручную: положить файлы
.devin/skills/go-project-layout/SKILL.mdСтарый путь .windsurf/skills/ тоже читается
Через Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a opencodeClaude.ai
Упакуйте папку в zip и загрузите в Settings → Capabilities → Skills
По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов
Вопросы о go-project-layout
Как установить go-project-layout в Claude Code?
Выполните npx skills add eduardo-sl/go-agent-skills --skill go-project-layout -a claude-code. Скилл окажется в ~/.claude/skills/go-project-layout/SKILL.md.
Что делает go-project-layout?
Помогает разложить новый Go-проект: выбирает раскладку по размеру, задаёт правила для cmd/ и internal/, именование модуля и структуру main.go.
Чем он отличается от go-architecture-review и go-dependency-injection?
Этот скилл работает с новым проектом. Разбор существующей архитектуры — задача go-architecture-review, внедрение зависимостей — go-dependency-injection, настройка CI — go-ci.
Исходный текст
SKILL.md · MIT
---
name: go-project-layout
description: >
Scaffold new Go projects and services: directory structure, cmd/ and
internal/ conventions, when to use a flat layout, module naming, and main
package wiring. Use when: "new Go project", "scaffold a service", "create
project structure", "start a Go module", "how do I organize a new
service", "set up folder structure".
Not for: reviewing an existing architecture (go-architecture-review), DI
wiring (go-dependency-injection), CI setup (go-ci).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. Requires git for repository initialisation.
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*) Bash(git:*)
metadata:
author: eduardo-sl
version: "1.2.1"
---
# Go Project Layout
Structure follows size. The biggest layout mistake in Go is copying a
microservice skeleton for a 500-line tool — or growing a 50-package
service inside a flat directory. Match the layout to the project.
> Community default. A project skill or agent-config rule that explicitly
> supersedes `go-project-layout` takes precedence over this one.
## 1. Pick the Layout by Project Size
| Project | Layout |
|---|---|
| Small tool, single binary, <5 files | Flat: everything in package `main` at the root |
| Library for others to import | Root package named after the module, `internal/` for helpers |
| Service with one binary | `cmd/<name>/main.go` + `internal/` packages |
| Multiple binaries sharing code | `cmd/<name1>/`, `cmd/<name2>/` + `internal/` |
Never start with empty `pkg/`, `api/`, `docs/`, `build/` directories
"for later". Add structure when the code demands it, not before.
## 2. Module Naming
```bash
# ✅ Good — repository path, lowercase
go mod init github.com/acme/payment-service
# ❌ Bad — not fetchable, uppercase, or vanity without DNS
go mod init PaymentService
go mod init payment_service
```
The last path element should match what users will see: for a library,
it becomes the default import name.
## 3. Service Layout (the default for APIs and workers)
```text
payment-service/
├── cmd/
│ └── payment-api/
│ └── main.go # flag/env parsing, wiring, Run() — nothing else
├── internal/
│ ├── domain/ # core types, business rules; zero external deps
│ ├── service/ # use cases orchestrating domain + stores
│ ├── store/ # data access implementations (postgres/, redis/)
│ ├── handler/ # HTTP/gRPC adapters
│ └── config/ # config loading and validation
├── migrations/ # if the service owns a database
├── go.mod
├── Makefile
└── README.md
```
Rules:
- `internal/` by default — the compiler enforces that nobody outside the
module imports it. Promote to a public package only on demand.
- `pkg/` only when external consumers exist AND the module also has
private code. When in doubt, don't create it.
- Dependencies point inward: `handler → service → domain ← store`.
`domain` imports neither `store` nor `handler`.
## 4. Thin main, Runnable Run
Keep `main.go` to wiring plus a delegating call, so the app is testable:
```go
func main() {
if err := run(context.Background(), os.Args[1:], os.Getenv); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(ctx context.Context, args []string, getenv func(string) string) error {
cfg, err := config.Load(getenv)
if err != nil {
return fmt.Errorf("load config: %w", err)
}
db, err := store.Open(ctx, cfg.DatabaseURL)
if err != nil {
return fmt.Errorf("open db: %w", err)
}
defer db.Close()
svc := service.New(store.NewUserRepo(db))
srv := handler.NewServer(cfg.Addr, svc)
return srv.ListenAndServe(ctx)
}
```
- `os.Exit` appears exactly once, in `main`.
- `run` takes its dependencies (`args`, `getenv`) so tests can call it.
- No `init()` functions for wiring — explicit construction order only.
## 5. Library Layout
```text
retry/
├── retry.go # package retry — the API, in the root
├── retry_test.go
├── backoff.go # same package, split by topic
├── internal/
│ └── clock/ # implementation details users must not import
├── examples_test.go # Example* functions shown in godoc
└── go.mod
```
- The root directory IS the package. No `src/`, no `lib/`.
- One package per concept. Resist `util`, `common`, `helpers` — name
packages after what they provide (`retry`, `clock`, `httpsign`).
## 6. Naming Rules for Directories and Packages
- Package name == directory name, short, lowercase, no underscores:
`store/postgres`, not `store/postgres_impl`.
- Don't stutter: `payment.Service`, not `payment.PaymentService`.
- Binary names in `cmd/` are user-facing: `cmd/payment-api`,
hyphenated is fine (directory only holds package `main`).
## 7. Files That Belong at the Root
- `go.mod`, `go.sum`, `README.md`, `LICENSE`, `Makefile`,
`.golangci.yml`, `Dockerfile` (single-binary projects).
- Do NOT create: `src/` (un-idiomatic), `vendor/` (unless the team
explicitly vendors), one-file packages like `types/` or `models/`
that become dumping grounds.
## 8. Configuration
- One config struct, loaded from the environment in one place
(`internal/config`), validated at startup — fail fast with every missing
or invalid value listed, not the first one.
- Flags for CLIs; environment variables for services (12-factor); defaults
in code. No config files baked into images, no environment-specific
branches (`if env == "prod"`) in business code.
- Secrets come from the environment or a secret manager, never from flags
(`ps` shows argv) or the repository.
## 9. One Module or Several
Default to one module per repository. Split into modules only when parts
are versioned and released independently (a public client library next to
a service). Develop across modules locally with `go.work`; don't commit
`replace => ../path` directives.
## Scaffolding Procedure
1. Ask/decide: tool, library, or service? How many binaries?
2. `go mod init <repo-path>`, then set the `go` directive deliberately —
since Go 1.26, `go mod init` writes the previous release
(`go 1.(N-1).0`), not the toolchain's.
3. Create only the directories the first feature needs.
4. Write `main.go` with the thin-main pattern above, and a config struct.
5. Pin developer tools as module tools (`go get -tool ...`, Go 1.24+) and
add `Makefile` targets: `build`, `test`, `lint`.
6. Verify: `go build ./...` and `go vet ./...` pass on the skeleton.
## Verification Checklist
1. Layout matches project size — no empty scaffolding directories
2. Module path is the fetchable repository path
3. All non-public packages live under `internal/`
4. `main.go` is thin: parse, wire, call `run`, exit
5. `os.Exit` only in `main`; no wiring in `init()`
6. Dependencies flow inward; `domain` has zero infrastructure imports
7. No `util`/`common`/`helpers`/`models` grab-bag packages
8. Package names match directories, lowercase, no stutter
9. `go build ./...` passes on the fresh skeleton
10. Config loaded and validated in one place at startup; no secrets in flags
11. One module unless parts are released independently; no committed local `replace`
© eduardo-sl · MIT · eduardo-sl/go-agent-skills