Go Style

gofmt. No exceptions. Generated code too.

Source baseline: apps/cloud/apps/dedalus_as/docs/style/. Source: apps/cloud/apps/dedalus_as/docs/style/

The full Go reference spans ~7000 lines across three documents: guide, decisions, and best practices. The .claude/skills/go-style skill loads the complete reference when needed.

File Header

Copyright line, then package comment. Algorithmic preamble for non-trivial algorithms between copyright and package declaration.

Naming

  • MixedCaps or mixedCaps. No underscores (except test functions, generated code, syscall).
  • Package names: concise, lowercase, no underscores. Avoid util, common, helper.
  • Receiver names: short (1-2 letters), abbreviation of type, consistent.
  • Constants: MixedCaps (not SCREAMING_SNAKE).
  • Initialisms: same case throughout. URL or url, never Url. ID not Id.
  • No Get prefix for getters.
  • Do not repeat package name at callsite: yamlconfig.Parse not yamlconfig.ParseYAMLConfig.

Hard Limits

Files target 400 lines, strong refactor signal at 500. Functions 70 lines. Nesting 3 levels. Arguments 5.

Style Priority Order

  1. Clarity (purpose is obvious to readers)
  2. Simplicity (simplest way possible)
  3. Concision (high signal-to-noise)
  4. Maintainability (easy to modify correctly)
  5. Consistency (matches the rest of the codebase)

Error Handling

if err != nil immediately after fallible calls. Wrap errors with fmt.Errorf("context: %w", err). Sentinel errors: var ErrDeclined = errors.New("creditcard: declined"). Error messages: lowercase, no punctuation at end.

Testing

Table-driven tests for repetitive cases. Test helpers with t.Helper(). Standard testing preferred over testify.

Imports

Three groups separated by blank lines: stdlib, external, internal.

Go Contract

Concern Default Banned pattern Proof
Formatting gofmt for all code, generated code included Manual formatting exceptions gofmt/CI
Names Short package and receiver names, consistent initialisms util, common, helper, Get* getters Review and lint
Errors Immediate if err != nil, %w wrapping with context Ignored errors or punctuation-heavy messages Unit test for error wrapping when behavior depends on it
Tests Table-driven tests for repeated cases Copy-paste case tests with hidden differences Standard go test
Boundaries Packages expose small domain APIs Deep imports across unrelated packages Import review

Proof

Go proof is boring on purpose: gofmt, go test, and a small test around any new error, boundary, or table-driven behavior. When a package boundary changes, review call sites for package-name repetition and deep import drift.

Style Rule Contract

This page follows Style Rule Contract: name the default pattern, banned pattern, reason, exception, proof, and codification path clearly enough that the next agent can apply the rule without asking Kevin again. If a local repo has a stricter rule, follow the local rule and update the wiki when the decision becomes durable.


Timeline