Use when naming any Go identifier — packages, types, functions, methods, variables, constants, or receivers — to ensure idiomatic, clear names. Also use when a user is creating new types, packages, or exported APIs, even if they don't explicitly ask about naming conventions. Does not cover package organization (see go-packages).
---
name: go-naming
description: Use when naming any Go identifier — packages, types, functions, methods, variables, constants, or receivers — to ensure idiomatic, clear names. Also use when a user is creating new types, packages, or exported APIs, even if they don't explicitly ask about naming conventions. Does not cover package organization (see go-packages).
license: Apache-2.0
metadata:
sources: "Google Style Guide, Uber Style Guide"
allowed-tools: Bash(bash:*)
---
# Go Naming Conventions
## Available Scripts
- **`scripts/check-naming.sh`** — Scans Go code for naming anti-patterns: SCREAMING_SNAKE_CASE constants, Get-prefixed getters, bad package names (util/helper/common), and receivers named "this"/"self". Run `bash scripts/check-naming.sh --help` for options.
## Core Principle
Names should:
- Not feel repetitive when used
- Take context into consideration
- Not repeat concepts that are already clear
Naming is more art than science—Go names tend to be shorter than in other
languages.
---
## Naming Decision Flow
```
What are you naming?
├─ Package → Short, lowercase, singular noun (no underscores, no mixedCaps)
├─ Interface → Method name + "-er" suffix when single-method (Reader, Writer)
├─ Receiver → 1-2 letter abbreviation of type (c for Client); consistent across methods
├─ Constant → MixedCaps; use iota for enums; no ALL_CAPS
├─ Exported func → Verb or verb-phrase in MixedCaps; no Get prefix for getters
├─ Variable → Length proportional to scope distance
│ ├─ Tiny scope (1-7 lines) → single letter (i, n, r)
│ ├─ Medium scope → short word (count, buf)
│ └─ Package-level / wide → descriptive (userAccountCount)
└─ Any name → Check: does it repeat package name or context? If yes, shorten it
```
---
## MixedCaps (Required)
> **Normative**: All Go identifiers must use MixedCaps.
Underscores are allowed only in: test functions (`TestFoo_InvalidInput`),
generated code, and OS/cgo interop.
---
## Package Names
> **Normative**: Packages must be lowercase with no underscores.
Short, lowercase, singular nouns. Avoid generic names like `util`, `common`,
`helper` — prefer specific names: `stringutil`, `httpauth`, `configloader`.
```go
// Good: user, oauth2, tabwriter
// Bad: user_service, UserService, count (shadows var)
```
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when naming packages, deciding on import aliases, or choosing between generic and specific package names.
---
## Interface Names
> **Advisory**: One-method interfaces use "-er" suffix.
Name one-method interfaces by the method plus `-er`: `Reader`, `Writer`,
`Formatter`. Honor canonical method names (`Read`, `Write`, `Close`, `String`)
and their signatures.
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when defining new interfaces or implementing well-known method signatures.
---
## Receiver Names
> **Normative**: Receivers must be short abbreviations, used consistently.
One or two letters abbreviating the type, consistent across all methods:
`func (c *Client) Connect()`, `func (c *Client) Send()`.
Never use `this` or `self`.
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when choosing receiver names or ensuring consistency across methods.
---
## Constant Names
> **Normative**: Constants use MixedCaps, never ALL_CAPS or K prefix.
Name constants by role, not value: `MaxRetries` not `Three`,
`DefaultPort` not `Port8080`.
```go
const MaxPacketSize = 512
const defaultTimeout = 30 * time.Second
```
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when naming constants or choosing between role-based and value-based names.
---
## Initialisms and Acronyms
> **Normative**: Initialisms maintain consistent case throughout.
Initialisms (URL, ID, HTTP, API) must be all uppercase or all lowercase:
`HTTPClient`, `userID`, `ParseURL()` — not `HttpClient`, `orderId`, `ParseUrl()`.
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when using initialisms in compound names or for the full case table.
---
## Function and Method Names
> **Advisory**: No `Get` prefix for simple accessors; use verb-like names for actions.
Getter for field `owner` is `Owner()`, not `GetOwner()`. Setter is
`SetOwner()`. Use `Compute` or `Fetch` for expensive operations.
When functions differ only by type, include type at the end:
`ParseInt()`, `ParseInt64()`.
> Read [references/IDENTIFIERS.md](references/IDENTIFIERS.md) when designing getter/setter APIs or naming function variants.
---
## Variable Names
Variable naming balances brevity with clarity. Key principles:
- **Scope-based length**: Short names (`i`, `v`) for small scopes; longer,
descriptive names for larger scopes
- **Single-letter conventions**: Use familiar patterns (`i` for index,
`r`/`w` for reader/writer)
- **Avoid type in name**: Use `users` not `userSlice`, `name` not `nameString`
- **Prefix unexported globals**: Use `_` prefix for package-level unexported
vars/consts to prevent shadowing
```go
for i, v := range items { ... } // small scope
pendingOrders := filterPending(orders) // larger scope
const _defaultPort = 8080 // unexported global
```
> Read [references/VARIABLES.md](references/VARIABLES.md) when naming local variables in functions over 15 lines.
---
## Avoiding Repetition
Go names should not feel repetitive when used. Consider the full context:
- **Package + symbol**: `widget.New()` not `widget.NewWidget()`
- **Receiver + method**: `p.Name()` not `p.ProjectName()`
- **Context + type**: In package `sqldb`, use `Connection` not `DBConnection`
> Read [references/REPETITION.md](references/REPETITION.md) when a package name and its exported symbols feel redundant.
---
## Avoid Built-In Names
Never shadow Go's predeclared identifiers (`error`, `string`, `len`, `cap`,
`append`, `copy`, `new`, `make`, etc.) as variable, parameter, or type names.
**For detailed guidance**: See `go-declarations` — "Avoid Using Built-In Names"
section.
---
## Quick Reference
| Element | Rule | Example |
|---------|------|---------|
| Package | lowercase, no underscores | `package httputil` |
| Exported | MixedCaps, starts uppercase | `func ParseURL()` |
| Unexported | mixedCaps, starts lowercase | `func parseURL()` |
| Receiver | 1-2 letter abbreviation | `func (c *Client)` |
| Constant | MixedCaps, never ALL_CAPS | `const MaxSize = 100` |
| Initialism | consistent case | `userID`, `XMLAPI` |
| Variable | length ~ scope size | `i` (small), `userCount` (large) |
| Built-in names | Never shadow predeclared identifiers | See `go-declarations` |
> **Validation**: After renaming identifiers, run `bash scripts/check-naming.sh` to verify no naming anti-patterns remain. Then run `go build ./...` to confirm the rename didn't break anything.
## Related Skills
- **Interface naming**: See [go-interfaces](../go-interfaces/SKILL.md) when naming interfaces with the `-er` suffix or choosing receiver types
- **Package naming**: See [go-packages](../go-packages/SKILL.md) when naming packages, avoiding `util`/`common`, or resolving import collisions
- **Error naming**: See [go-error-handling](../go-error-handling/SKILL.md) when naming sentinel errors (`ErrFoo`) or custom error types
- **Declaration scope**: See [go-declarations](../go-declarations/SKILL.md) when variable name length depends on scope or when avoiding built-in shadowing
- **Style principles**: See [go-style-core](../go-style-core/SKILL.md) when balancing clarity vs concision in identifier names
Creator's repository · cxuu/golang-skills
License: Apache-2.0