go-naming · eduardo-sl — Claude Code skill: what it does, how to install
Applies Go naming conventions from Effective Go to packages, methods, acronyms, and errors. Helps prevent stuttering names like order.OrderService.
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a claude-codeWhat go-naming does
The skill enforces naming guidelines from Effective Go across your codebase. It inspects packages, files, interfaces, receivers, and constants. Package names stay singular and lowercase, avoiding generic catch-alls like common or util. It also eliminates stuttering at call sites, keeping http.Client instead of http.HTTPClient.
Rules maintain consistent casing for acronyms (userID, ServeHTTP). Getters drop the Get prefix. Receivers take one or two letters instead of this or self. Sentinel errors require Err, while custom error types end in Error.
Verification requires a local Go toolchain with access to gofmt. The skill does not reformat code or rename symbols across the project. Separate skills handle those tasks.
What it helps with
- eliminate stuttering package names like user.NewUser
- standardize initialism casing across types such as userID and ServeHTTP
- clean up getters by dropping the Get prefix
- name sentinel errors and custom error types consistently
Example prompts for the agent
- Review the naming in internal/orders against Go conventions
- What should I name the client type in package httpsign without stuttering?
- Audit receiver names and enum constants in cache.go
How to install go-naming
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a claude-code2Manually: put the files in place
~/.claude/skills/go-naming/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/go-naming/
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a codex2Manually: put the files in place
.agents/skills/go-naming/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a cursor2Manually: put the files in place
.cursor/skills/go-naming/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install eduardo-sl/go-agent-skills go-naming2Manually: put the files in place
.github/skills/go-naming/SKILL.md1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a gemini-cli2Platform CLI
gemini skills install https://github.com/eduardo-sl/go-agent-skills --path 'skills/(code-quality)/go-naming'Manually: put the files in place
.devin/skills/go-naming/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-naming -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about go-naming
How do I install go-naming in Claude Code?
Run npx skills add eduardo-sl/go-agent-skills --skill go-naming -a claude-code. The skill file is saved to ~/.claude/skills/go-naming/SKILL.md.
What does go-naming cover?
It guides the agent on idiomatic naming for packages, methods, interfaces, receivers, constants, and errors. It prevents anti-patterns like Get prefixes and generic helpers packages.
Does go-naming handle code formatting or import sorting?
No, it focuses solely on naming identifiers. Formatting and project-wide renaming are handled by separate skills.
Source text
SKILL.md · MIT
--- name: go-naming description: > Go naming conventions for packages, files, types, functions, methods, receivers, variables, constants, errors, acronyms and tests, grounded in Effective Go and Go Code Review Comments. Use when: "what should I name this", "name this package", "naming review", "is this name idiomatic", "stuttering names", "Get prefix", "acronym casing", "error variable name", "receiver name". Not for: formatting, imports and declarations (go-coding-standards), carrying out a rename across the codebase (go-semantic-tools, go-refactoring). user-invocable: true license: MIT compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*) metadata: author: eduardo-sl version: "1.0.0" --- # Go Naming In Go the package name is part of every call site, capitalization decides visibility, and short names are the norm. A good name reads well *where it is used*, not where it is declared. > Community default. A project skill or agent-config rule that explicitly > supersedes `go-naming` takes precedence over this one. Detailed reference material, loaded on demand: - `references/examples.md` — before/after renames for every rule below, including the initialism and stuttering edge cases. Read a reference file only when the summary below is not enough. ## 1. Quick Reference | Element | Convention | Example | |---|---|---| | Package | short, lowercase, one word, singular | `order`, `httpsign`, `postgres` | | File | lowercase, `_` allowed, named after its main type or concern | `order_service.go`, `order_service_test.go` | | Exported identifier | `MixedCaps` | `ParseToken`, `MaxRetries` | | Unexported identifier | `mixedCaps` | `parseToken`, `maxRetries` | | Initialism | all one case | `URL`, `userID`, `ServeHTTP`, `xmlParser` | | Getter / setter | `Owner()` / `SetOwner()` | never `GetOwner()` | | Constructor | `New` for the package's main type, `NewThing` otherwise | `ring.New`, `http.NewRequest` | | Panicking variant | `Must` prefix | `template.Must`, `regexp.MustCompile` | | Functional option | `With` + setting | `WithTimeout`, `WithLogger` | | One-method interface | method + `-er` | `Reader`, `Notifier` | | Receiver | 1-2 letters, same on every method | `func (s *Server)` | | Sentinel error | `Err` prefix (`err` unexported) | `ErrNotFound`, `errClosed` | | Error type | `Error` suffix | `ValidationError` | | Enum constant | type name prefix, zero = unknown | `StatusUnknown`, `StatusActive` | | Test | `Test` + function, `Test` + type `_` method | `TestParse`, `TestCache_Get` | ## 2. Packages - Short, lowercase, single word: no underscores, no `mixedCaps`, no plural (`order`, not `orders`). - Name it after what it *provides*: `retry`, `httpsign`, `postgres`. Never `util`, `common`, `helpers`, `misc`, `base`, `models`, `types` — they say nothing and collect everything. - The directory name and the package name match. - Avoid names callers want for their variables (`url`, `user`, `buf`) when the package is imported widely; a call site with `u := user.New()` reads better than shadowing the package. ## 3. Don't Stutter The package name is always present at the call site, so don't repeat it: ```go // ✅ Good — reads once http.Client order.Service user.New() config.Load() // ❌ Bad — says it twice http.HTTPClient order.OrderService user.NewUser() config.LoadConfig() ``` The rule covers every exported name in the package, not just the main type: in package `dbpool`, `Pool`, `Status` and `Option` — not `DBPool`, `PoolStatus`, `PoolOption`. ## 4. MixedCaps, Initialisms and Constants - Every identifier is `MixedCaps` or `mixedCaps`. Underscores appear only in test names (`TestCache_Get`), generated code, and cgo. - An initialism keeps one case throughout: `URL`, `ID`, `HTTP`, `JSON`, `API` — `userID`, `parseURL`, `ServeHTTP`, `HTTPServer`, `xmlHTTPRequest`. Never `UserId`, `ParseUrl`, `HttpServer`. - Constants are `MixedCaps` like everything else: `MaxRetries`, not `MAX_RETRIES` — case already means "exported" in Go. - Name constants for their role, not their value: `DefaultPort`, not `Port8080`. - Do not shadow predeclared identifiers: `len`, `cap`, `new`, `make`, `close`, `copy`, `error`, `string`, `min`, `max`. ## 5. Functions and Methods - Getters drop `Get`: `u.Name()`, and the setter is `u.SetName()`. `Is`/`Has`/`Can` stay on boolean predicates: `IsActive()`. - Constructors: `New` when the package has one main type, `NewThing` otherwise. A constructor that panics on bad input is `MustThing`. - Canonical names carry a contract. Call a method `Read`, `Write`, `Close`, `Flush`, `String`, `Error` or `ServeHTTP` only if it has the standard signature and meaning — and if it does, use that name (`String()`, never `ToString()`). - Name for what the caller gets, not how it is computed: `Users()`, not `QueryAndBuildUserList()`. - Format-string variants end in `f`: `Errorf`, `Logf`. ## 6. Variables and Receivers - Name length grows with scope: `i`, `n`, `err`, `ctx`, `buf` inside a few lines; `retryTimeout`, `pendingOrders` across a function; full words at package level. - Don't put the type in the name (`userSlice` → `users`, `nameStr` → `name`), and don't repeat context the reader already has (`order.ID` inside `type Order`, not `order.OrderID`). - Receivers are one or two letters from the type (`s *Server`, `rw *responseWriter`), the same on every method of the type — never `this` or `self`. - Unexported package-level variables may take a `_` prefix (`_defaultTimeout`) to keep them distinct from locals — the Uber style convention. Follow whichever the codebase already uses. - Boolean names read as a question: `isReady`, `hasChildren`, `canRetry`. ## 7. Types and Interfaces - Types are nouns: `Request`, `FileHeader`, `RetryPolicy`. - A one-method interface is the method plus `-er`: `Reader`, `Notifier`, `Validator`. Never an `I` prefix or `Interface` suffix. - Name an interface after the behavior the consumer needs, in the consumer's package (`orderStore` in the service), not after the implementation it happens to have. ## 8. Errors - Exported sentinels `ErrNotFound`, unexported `errClosed`. - Error types end in `Error`: `NotFoundError`, `SyntaxError`. - Error strings are lowercase with no trailing punctuation, prefixed with the package or operation: `"order: invalid quantity"`. They get wrapped into longer messages, so they must read mid-sentence. ## 9. Enums and Tests - Enum constants are prefixed with their type and start with an explicit `Unknown` at zero: `StatusUnknown`, `StatusActive`, `StatusClosed`. - Tests: `TestParse`, `TestCache_Get`, `BenchmarkParse`, `ExampleCache_Get` (the example name must match a real identifier, or `go vet` complains). - Subtest names are short lowercase phrases — `"empty input"`, `"expired token"` — because `go test -run 'TestParse/empty_input'` selects them. ## Applying a Rename Rename with gopls, not search-and-replace: it follows the type graph and refuses renames that would break interface satisfaction (the go-semantic-tools skill). Then grep struct tags, templates and SQL for the old name — gopls does not see them. Exported names in a published library need a deprecation cycle (the go-refactoring skill). ## Verification Checklist 1. No package named `util`, `common`, `helpers`, `models`, `types`, `misc` or `base` 2. No exported name repeats its package name 3. Initialisms keep one case (`ID`, `URL`, `HTTP`); no `ALL_CAPS` constants 4. No `Get` prefix on getters; `Must` only on panicking functions 5. Canonical method names (`String`, `Read`, `Close`, …) have canonical signatures 6. Receivers are short and identical across a type's methods; no `this`/`self` 7. Sentinels use `Err`, error types end in `Error`, error strings are lowercase 8. Enum constants carry the type prefix and an `Unknown` zero value 9. No predeclared identifier is shadowed 10. Renames done with gopls; tags and templates checked afterwards
© eduardo-sl · MIT · eduardo-sl/go-agent-skills
Similar skills
All skills for Programming languages →go-naming by other authors comes first.