Golang-skills go-naming

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).

install
source · Clone the upstream repo
git clone https://github.com/cxuu/golang-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/cxuu/golang-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/go-naming" ~/.claude/skills/cxuu-golang-skills-go-naming && rm -rf "$T"
manifest: skills/go-naming/SKILL.md
source content

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
.

// Good: user, oauth2, tabwriter
// Bad:  user_service, UserService, count (shadows var)

Read 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 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 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
.

const MaxPacketSize = 512
const defaultTimeout = 30 * time.Second

Read 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 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 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
for i, v := range items { ... }           // small scope
pendingOrders := filterPending(orders)    // larger scope
const _defaultPort = 8080                 // unexported global

Read 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 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

ElementRuleExample
Packagelowercase, no underscores
package httputil
ExportedMixedCaps, starts uppercase
func ParseURL()
UnexportedmixedCaps, starts lowercase
func parseURL()
Receiver1-2 letter abbreviation
func (c *Client)
ConstantMixedCaps, never ALL_CAPS
const MaxSize = 100
Initialismconsistent case
userID
,
XMLAPI
Variablelength ~ scope size
i
(small),
userCount
(large)
Built-in namesNever shadow predeclared identifiersSee
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 when naming interfaces with the
    -er
    suffix or choosing receiver types
  • Package naming: See go-packages when naming packages, avoiding
    util
    /
    common
    , or resolving import collisions
  • Error naming: See go-error-handling when naming sentinel errors (
    ErrFoo
    ) or custom error types
  • Declaration scope: See go-declarations when variable name length depends on scope or when avoiding built-in shadowing
  • Style principles: See go-style-core when balancing clarity vs concision in identifier names