agentleFS
eduardo-sleduardo-sl/go-agent-skills/skills/(code-quality)/go-naming/SKILL.md

go-naming

Skill85 starsChanged 18 days agoMITView on GitHub

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

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 3 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Read a reference file only when the summary below is not enough.

    line 36
  2. Very specific:

    Avoid names callers want for their variables (url, user, buf) when the package is imported widely.

    line 66
  3. Very specific:

    Every identifier is MixedCaps or mixedCaps.

    line 88
  4. Very specific:

    Never UserId, ParseUrl, HttpServer.

    line 92
  5. Very specific:

    Do not shadow predeclared identifiers: len, cap, new, make, close, copy, error, string, min, max.

    line 97
  6. Very specific:

    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 …

    line 119
  7. Very specific:

    No package named util, common, helpers, models, types, misc or base

    line 167
  8. Distinctive:

    No exported name repeats its package name

    line 168
  9. Distinctive:

    No predeclared identifier is shadowed

    line 175

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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

ElementConventionExample
Packageshort, lowercase, one word, singularorder, httpsign, postgres
Filelowercase, _ allowed, named after its main type or concernorder_service.go, order_service_test.go
Exported identifierMixedCapsParseToken, MaxRetries
Unexported identifiermixedCapsparseToken, maxRetries
Initialismall one caseURL, userID, ServeHTTP, xmlParser
Getter / setterOwner() / SetOwner()never GetOwner()
ConstructorNew for the package's main type, NewThing otherwisering.New, http.NewRequest
Panicking variantMust prefixtemplate.Must, regexp.MustCompile
Functional optionWith + settingWithTimeout, WithLogger
One-method interfacemethod + -erReader, Notifier
Receiver1-2 letters, same on every methodfunc (s *Server)
Sentinel errorErr prefix (err unexported)ErrNotFound, errClosed
Error typeError suffixValidationError
Enum constanttype name prefix, zero = unknownStatusUnknown, StatusActive
TestTest + function, Test + type _ methodTestParse, 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:

// ✅ 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

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.