Generated banner for Golang Naming
Generated logo for Golang Naming

Golang Naming

Samuel BertheCommunityCreated by samberDistributed by Samuel Berthe

  • Skill
  • Guidelines
  • Software development
  • MIT
  • No issues found

From the author

Go (Golang) naming conventions — covers packages, constructors, structs, interfaces, constants, enums, errors, booleans, receivers, getters/setters, functional options, acronyms, test functions, and subtest names. Use this skill when writing new Go code, reviewing or refactoring, choosing between naming alternatives (New vs NewTypeName, isConnected vs connected, ErrNotFound vs NotFoundError, StatusReady vs StatusUnknown at iota 0), debating Go package names (utils/helpers anti-patterns), or asking about Go naming best practices. Also trigger when the user mentions MixedCaps vs snake_case, ALL_CAPS constants, Get-prefix on getters, or error string casing. Do NOT use for general Go implementation questions that don't involve naming decisions.
— the description by samber

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides the definitive Go naming standards to ensure code readability and idiomatic consistency. It covers the full spectrum of Go identifiers, including package naming, struct and interface definitions, constructor patterns, error handling, and boolean predicates. By enforcing MixedCaps and avoiding stuttering, it helps developers write code that aligns with the Go community's 'clear is better than clever' philosophy.

What it does

  • Defines naming rules for packages, files, and exported/unexported identifiers.
  • Provides patterns for constructors, getters, setters, and boolean predicates.
  • Explains how to avoid stuttering and redundant naming in Go packages.
  • Standardizes error variable naming and error string formatting.
  • Offers guidance on acronym casing and receiver naming conventions.
  • Outlines conventions for table-driven test functions and subtests.

When to use it

  • When writing new Go code and deciding on identifier names.
  • During code reviews to identify non-idiomatic naming patterns.
  • When refactoring existing code to improve clarity and consistency.
  • When debating package structure or naming alternatives like New vs NewTypeName.
  • When resolving naming conflicts or choosing between different naming styles.

Advantages

  • Promotes idiomatic, readable, and maintainable Go code.
  • Reduces cognitive load by enforcing consistent naming across the codebase.
  • Prevents common naming pitfalls like stuttering and incorrect acronym casing.
  • Aligns code with standard library patterns and community expectations.

Usage examples

“How should I name a constructor for a struct named 'Client' in a package named 'api'?”
The skill advises using 'New()' to avoid stuttering, resulting in 'api.New()' instead of 'api.NewClient()'.
“Should I use 'is_connected' or 'isConnected' for a boolean field in a struct?”
The skill mandates 'MixedCaps' and 'is' prefixing, confirming 'isConnected' is the correct choice.
“What is the convention for naming an error variable?”
The skill specifies using the 'Err' prefix, such as 'ErrNotFound', and keeping error strings fully lowercase.
“How do I name a getter method for a field named 'port'?”
The skill instructs to omit the 'Get' prefix, recommending 'Port()' instead of 'GetPort()'.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/samber/golang-naming/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip golang-naming.zip -d .agents/skills

Documentation by samber

Community default. A company skill that explicitly supersedes samber/cc-skills-golang@golang-naming skill takes precedence.

Go Naming Conventions

Go favors short, readable names. Capitalization controls visibility — uppercase is exported, lowercase is unexported. All identifiers MUST use MixedCaps, NEVER underscores.

"Clear is better than clever." — Go Proverbs

"Design the architecture, name the components, document the details." — Go Proverbs

To ignore a rule, just add a comment to the code.

Quick Reference

ElementConventionExample
Packagelowercase, single word, _test suffix OK for test filesjson, http, tabwriter, http_test
Filelowercase, underscores OKuser_handler.go
Exported nameUpperCamelCaseReadAll, HTTPClient
UnexportedlowerCamelCaseparseToken, userCount
Interfacemethod name + -erReader, Closer, Stringer
StructMixedCaps nounRequest, FileHeader
ConstantMixedCaps (not ALL_CAPS)MaxRetries, defaultTimeout
Receiver1-2 letter abbreviationfunc (s *Server), func (b *Buffer)
Error variableErr prefixErrNotFound, ErrTimeout
Error typeError suffixPathError, SyntaxError
ConstructorNew (single type) or NewTypeName (multi-type)ring.New, http.NewRequest
Boolean fieldis, has, can prefix on fields and methodsisReady, IsConnected()
Test functionTest + function nameTestParseToken
Acronymall caps or all lowerURL, HTTPServer, xmlParser
Variant: contextWithContext suffixFetchWithContext, QueryContext
Variant: in-placeIn suffixSortIn(), ReverseIn()
Variant: errorMust prefixMustParse(), MustLoadConfig()
Option funcWith + field nameWithPort(), WithLogger()
Enum (iota)type name prefix, zero-value = unknownStatusUnknown at 0, StatusReady
Named returndescriptive, for docs only(n int, err error)
Error stringlowercase (incl. acronyms), no punctuation"image: unknown format", "invalid id"
Import aliasshort, only on collisionmrand "math/rand", pb "app/proto"
Format funcf suffixErrorf, Wrapf, Logf
Test table fieldsgot/expected prefixesinput string, expected int

MixedCaps

All Go identifiers MUST use MixedCaps (or mixedCaps). NEVER use underscores in identifiers — the only exceptions are test function subcases (TestFoo_InvalidInput), generated code, and OS/cgo interop. This is load-bearing, not cosmetic — Go's export mechanism relies on capitalization, and tooling assumes MixedCaps throughout.

// ✓ Good
MaxPacketSize
userCount
parseHTTPResponse

// ✗ Bad — these conventions conflict with Go's export mechanism and tooling expectations
MAX_PACKET_SIZE   // C/Python style
max_packet_size   // snake_case
kMaxBufferSize    // Hungarian notation

Avoid Stuttering

Go call sites always include the package name, so repeating it in the identifier wastes the reader's time — http.HTTPClient forces parsing "HTTP" twice. A name MUST NOT repeat information already present in the package name, type name, or surrounding context.

// Good — clean at the call site
http.Client       // not http.HTTPClient
json.Decoder      // not json.JSONDecoder
user.New()        // not user.NewUser()
config.Parse()    // not config.ParseConfig()

// In package sqldb:
type Connection struct{}  // not DBConnection — "db" is already in the package name

// Anti-stutter applies to ALL exported types, not just the primary struct:
// In package dbpool:
type Pool struct{}        // not DBPool
type Status struct{}      // not PoolStatus — callers write dbpool.Status
type Option func(*Pool)   // not PoolOption

Frequently Missed Conventions

These conventions are correct but non-obvious — they are the most common source of naming mistakes:

Constructor naming: When a package exports a single primary type, the constructor is New(), not NewTypeName(). This avoids stuttering — callers write apiclient.New() not apiclient.NewClient(). Use NewTypeName() only when a package has multiple constructible types (like http.NewRequest, http.NewServeMux).

Boolean struct fields: Unexported boolean fields MUST use is/has/can prefix — isConnected, hasPermission, not bare connected or permission. The exported getter keeps the prefix: IsConnected() bool. This reads naturally as a question and distinguishes booleans from other types.

Error strings are fully lowercase — including acronyms. Write "invalid message id" not "invalid message ID", because error strings are often concatenated with other context (fmt.Errorf("parsing token: %w", err)) and mixed case looks wrong mid-sentence. Sentinel errors should include the package name as prefix: errors.New("apiclient: not found").

Enum zero values: Always place an explicit Unknown/Invalid sentinel at iota position 0. A var s Status silently becomes 0 — if that maps to a real state like StatusReady, code can behave as if a status was deliberately chosen when it wasn't.

Subtest names: Table-driven test case names in t.Run() should be fully lowercase descriptive phrases: "valid id", "empty input" — not "valid ID" or "Valid Input".

Detailed Categories

For complete rules, examples, and rationale, see:

  • Packages, Files & Import Aliasing — Package naming (single word, lowercase, no plurals), file naming conventions, import alias patterns (only use on collision to avoid cognitive load), and directory structure.

  • Variables, Booleans, Receivers & Acronyms — Scope-based naming (length matches scope: i for 3-line loops, longer names for package-level), single-letter receiver conventions (s for Server), acronym casing (URL not Url, HTTPServer not HttpServer), and boolean naming patterns (isReady, hasPrefix).

  • Functions, Methods & Options — Getter/setter patterns (Go omits Get so user.Name() reads naturally), constructor conventions (New or NewTypeName), named returns (for documentation only), format function suffixes (Errorf, Wrapf), and functional options (WithPort, WithLogger).

  • Types, Constants & Errors — Interface naming (Reader, Closer suffix with -er), struct naming (nouns, MixedCaps), constants (MixedCaps, not ALL_CAPS), enums (type name prefix like StatusReady), sentinel errors (ErrNotFound variables), error types (PathError suffix), and error message conventions (lowercase, no punctuation).

  • Test Naming — Test function naming (TestFunctionName), table-driven test field conventions (input, expected), test helper naming, and subcase naming patterns.

Common Mistakes

MistakeFix
ALL_CAPS constantsGo reserves casing for visibility, not emphasis — use MixedCaps (MaxRetries)
GetName() getterGo omits Get because user.Name() reads naturally at call sites. But Is/Has/Can prefixes are kept for boolean predicates: IsHealthy() bool not Healthy() bool
Url, Http, Json acronymsMixed-case acronyms create ambiguity (HttpsUrl — is it Https+Url?). Use all caps or all lower
this or self receiverGo methods are called frequently — use 1-2 letter abbreviation (s for Server) to reduce visual noise
util, helper packagesThese names say nothing about content — use specific names that describe the abstraction
http.HTTPClient stutteringPackage name is always present at call site — http.Client avoids reading "HTTP" twice
user.NewUser() constructorSingle primary type uses New() — user.New() avoids repeating the type name
connected bool fieldBare adjective is ambiguous — use isConnected so the field reads as a true/false question
"invalid message ID" errorError strings must be fully lowercase including acronyms — "invalid message id"
StatusReady at iota 0Zero value should be a sentinel — StatusUnknown at 0 catches uninitialized values
"not found" error stringSentinel errors should include the package name — "mypackage: not found" identifies the origin
userSlice type-in-nameTypes encode implementation detail — users describes what it holds, not how
Inconsistent receiver namesSwitching names across methods of the same type confuses readers — use one name consistently
snake_case identifiersUnderscores conflict with Go's MixedCaps convention and tooling expectations — use mixedCaps
Long names for short scopesName length should match scope — i is fine for a 3-line loop, userIndex is noise
Naming constants by valueValues change, roles don't — DefaultPort survives a port change, Port8080 doesn't
FetchCtx() context variantWithContext is the standard Go suffix — FetchWithContext() is instantly recognizable
sort() in-place but no InReaders assume functions return new values. SortIn() signals mutation
parse() panicking on errorMustParse() warns callers that failure panics — surprises belong in the name
Mixing With*, Set*, Use*Consistency across the codebase — With* is the Go convention for functional options
Plural package namesGo convention is singular (net/url not net/urls) — keeps import paths consistent
Wrapf without f suffixThe f suffix signals format-string semantics — Wrapf, Errorf tell callers to pass format args
Unnecessary import aliasesAliases add cognitive load. Only alias on collision — mrand "math/rand"
Inconsistent concept namesUsing user/account/person for the same concept forces readers to track synonyms — pick one name

Applying these fixes means renaming existing identifiers — → See samber/cc-skills-golang@golang-gopls skill to do it safely: its rename updates every call site across the workspace and refuses a rename that would break interface satisfaction, which a grep/sed or manual Edit-based rename silently misses.

Enforce with Linters

Many naming convention issues are caught automatically by linters: revive, predeclared, misspell, errname. See samber/cc-skills-golang@golang-lint skill for configuration and usage.

Cross-References

  • → See samber/cc-skills-golang@golang-code-style skill for broader formatting and style decisions

  • → See samber/cc-skills-golang@golang-structs-interfaces skill for interface naming depth and receiver design

  • → See samber/cc-skills-golang@golang-lint skill for automated enforcement (revive, predeclared, misspell, errname)

  • → See samber/cc-skills-golang@golang-gopls skill for safe rename when applying a naming fix

  • → See samber/cc-skills-golang@golang-refactoring skill for how to apply a rename safely at scale (gopls Rename/Inline, blast-radius mapping, staged PR workflow) once you've decided what to rename identifiers to

Files

references/types-errors.md

Types, Constants & Errors

Table of Contents

  • Interfaces

    • Single-Method Interfaces

    • Multi-Method Interfaces

    • Canonical Method Names

  • Structs

  • Constants

    • Enums (iota)

  • Errors

    • Sentinel Errors

    • Error Types

    • Error Strings

Interfaces

Single-Method Interfaces

Name them with the method name + -er suffix:

type Reader interface {
    Read(p []byte) (n int, err error)
}

type Stringer interface {
    String() string
}

type Closer interface {
    Close() error
}
Multi-Method Interfaces

Use a descriptive noun or compose from single-method interfaces:

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
Canonical Method Names

Honor established Go method names and their signatures. If your type implements Read, it MUST match io.Reader's signature. NEVER invent variations like ReadData or ToString — use String.

Method nameExpected interface
Readio.Reader
Writeio.Writer
Closeio.Closer
Stringfmt.Stringer
Errorerror
Lensort.Interface
ServeHTTPhttp.Handler

Structs

Name structs with MixedCaps nouns describing the entity. Fields follow exported/unexported rules.

type Server struct {
    Addr     string        // exported
    Handler  http.Handler  // exported
    timeout  time.Duration // unexported
}

NEVER suffix struct names with Struct, Object, or Data — they add no information.

Constants

Constants MUST use MixedCaps, NEVER ALL_CAPS. The name should explain the role, not the value.

// Good — MixedCaps, name explains purpose
const MaxRetries = 3
const defaultTimeout = 30 * time.Second
const DefaultPort = 8080

// Bad — ALL_CAPS is not idiomatic Go
const MAX_RETRIES = 3
const DEFAULT_TIMEOUT = 30

// Bad — name is the value, not the purpose
const Three = 3
const Port8080 = 8080
Enums (iota)

Prefix enum values with the type name to avoid collisions and improve readability at the call site.

type Status int

const (
    StatusUnknown Status = iota // zero value = unknown/invalid
    StatusReady
    StatusRunning
    StatusDone
)

type Color int

const (
    ColorRed Color = iota + 1  // skip zero to catch uninitialized values
    ColorGreen
    ColorBlue
)

Always protect the zero value. A var s Status will silently be 0 — if that maps to a real state like StatusReady, code can behave as if a status was deliberately chosen when it wasn't. Either place an explicit Unknown sentinel at iota 0, or start at iota + 1. This is not optional — uninitialized enums are a common source of silent bugs.

Errors

Sentinel Errors

Sentinel error variables use the Err prefix. Error strings SHOULD include the package name as prefix to identify the origin when errors are wrapped:

// Good — package prefix identifies origin
var ErrNotFound = errors.New("mypackage: not found")
var ErrPermissionDenied = errors.New("mypackage: permission denied")
var ErrTimeout = errors.New("mypackage: operation timed out")

// Bad — bare strings lose origin when wrapped
var ErrNotFound = errors.New("not found")
Error Types

Custom error types use the Error suffix:

type PathError struct {
    Op   string
    Path string
    Err  error
}

type SyntaxError struct {
    Offset int64
    msg    string
}
Error Strings

Error strings MUST be fully lowercase — including acronyms — and MUST NOT end with punctuation, because they are often printed following other context (fmt.Errorf("parsing config: %w", err)). Acronyms that would normally be capitalized in identifiers (ID, URL, HTTP) become lowercase in error strings.

// Good — lowercase including acronyms, no punctuation
errors.New("image: unknown format")
errors.New("mypackage: invalid message id")     // "id" not "ID"
errors.New("mypackage: invalid url")             // "url" not "URL"
fmt.Errorf("decoding config: %w", err)

// Bad — capitalized, acronyms, punctuation
errors.New("Image: Unknown format.")
errors.New("mypackage: invalid message ID")      // ID should be lowercase in error strings
fmt.Errorf("Failed to decode config: %w.", err)

Requirements and compatibility

Written for: Claude Code, OpenAI Codex

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Declares allowed tools, Claude Code frontmatter

The author says: Designed for Claude Code, Codex or similar harness, and for projects using Golang.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
samber
Publisher
Samuel Berthe (Community)
Distributed by
Samuel Berthe
Source
samber/cc-skills-golang · skills/golang-naming · commit bb1d43d
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by samber or Samuel Berthe.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download golang-naming.zip