mcpField
G
go-idiomatic

go-idiomatic

github.com/o-marsters-1997Development0100 installsUpdated today
Repository

About go-idiomatic

Go Idiomatic defines repository-specific Go conventions for developers making or reviewing changes. It organizes guidance by topic and routes detailed practices to references and related skills.

Key features

  1. 01Error handling and logging rules
  2. 02Code organization conventions
  3. 03Function and naming guidance
  4. 04Routes to topic-specific references
  5. 05Go tooling requirements

Use cases

  1. 01Implementing a Go repository change
  2. 02Reviewing Go code conventions
  3. 03Choosing a reference for a specific Go topic

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/o-marsters-1997/my-claude-code --skill go-idiomatic

After installing, type/go-idiomaticin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

evals/
evals.json
evals/files/optional-field/
go.mod
evals/files/optional-field/internal/user/
user.go
evals/files/refactor-store/
go.mod
evals/files/refactor-store/helpers/
helpers.go
evals/files/refactor-store/store/
store.go
evals/files/server-settings/
go.mod
evals/files/server-settings/cmd/app/
main.go
evals/files/server-settings/internal/server/
server.go
references/
concurrency.md
database.md
errors.md
exec.md
http-client.md
logging.md
middleware.md
optional.md
patterns.md
secrets.md
value-vs-pointer.md

Details

From the project README

Go Idiomatic

This repo's rules for Go, where they differ from or sharpen general Go practice. The rules below apply to every change; the references hold the detail and worked examples.

Where to Look

Route to the right reference before reading further:

If you're working on…Load this
Goroutines, channels, sync primitives, errgroup, leaks, racesreferences/concurrency.md
Adding a sentinel or error type, translating errors between packages or to HTTP responses, logging where an error came from, cleanup in defer, panicreferences/errors.md
HTTP middleware: request Content-Type, CSRF, session cookie attributesreferences/middleware.md
Storing session or reset tokens, password reset or change, encrypting a columnreferences/secrets.md
Giving main or a component a logger, choosing a level, CLI output vs logsreferences/logging.md
Interface design, zero values, identifier types, typed value sets, anti-patternsreferences/patterns.md
Writing or reviewing tests, benchmarks, fuzzing, test databasesthe go-testing skill
Optional fields or return values — when to use Option[T]references/optional.md
Pointer vs value receivers, mutation vs optionalityreferences/value-vs-pointer.md
Scaffolding a Go HTTP client for a third-party API, writing a NewXxxClient, or attaching auth to outbound HTTP callsreferences/http-client.md
Shelling out with os/exec to git, gh or another CLI, parsing its --json output, faking it in testsreferences/exec.md
Storing data in SQL: store package boundary, transactions, NULLs, constraint errors, pool setupreferences/database.md
Rendering html/template for htmx: page vs fragment vs redirect, HX-* headers, .tmpl filesthe htmx-go-templates skill

Errors and Logging

Nearly every change returns an error or reports one, so these rules apply to all Go work, not only to a task described as error handling:

  1. Wrap with fmt.Errorf("<verb> <noun>: %w", err). Error strings are lowercase, with no punctuation and no "failed to".
  2. Handle an error once: return it with context, or log it at the top of the chain. Never both.
  3. Export a sentinel only when a caller in another package branches on it. Define it where the condition is detected, and translate a dependency's errors into your own at the package seam.
  4. Never discard an error with _ =. Join a cleanup error into the returned error, or log it at Warn when there is nothing to return to.
  5. panic only for programmer errors: Must helpers on constant input, impossible cases.
  6. Only components where an error stops travelling (handlers, workers, long-lived services) take an injected *slog.Logger, as a constructor field. Code below them returns errors and takes no logger. main builds the one logger; nothing calls log.*, slog.Info or slog.Default().
  7. Log messages are constant; variable data goes in snake_case key-value attributes, with err for the error. Never log secrets or personal data.
  8. Output the user asked for goes to an injected io.Writer, not to the logger.

A routine return fmt.Errorf(...) or log line needs only these rules. Load references/errors.md when adding a sentinel or error type, turning an error into an HTTP response, wrapping a driver or outbound-call error, or handling a cleanup error, and references/logging.md when wiring a logger, choosing a level or separating CLI output.


Testing

Writing, editing or reviewing a _test.go file: load the go-testing skill, which owns how Go tests are written, including test databases. What to test (the kinds of test, what each is worth, the reusable patterns) is the repo's testing-policy when it ships one.


Code Organisation

  1. Applications keep main in cmd/<app>/main.go, which only wires dependencies, and everything else under internal/. pkg/ is for library modules imported from outside the repo; in an application it signals a public API that doesn't exist.
  2. Extract shared logic on the third repetition across meaningfully different packages, not the second. A helper coupled to one domain lives in internal/ next to its primary caller.
  3. Name a package by what it does (stringx, idgen, timeutil). utils is allowed only when it is used across many packages and imports nothing from internal/. helpers and common are never allowed: a real name is waiting to be found.
  4. No package-level state such as a global *sql.DB set in init(). Pass dependencies through constructors.
  5. main parses the environment once into a typed config struct, validates it, and exits on a bad value at startup rather than on the first request that needs it. Constructors receive only the fields they use, not the whole struct. Nothing below cmd/ calls os.Getenv.

Function Design

  1. Past 3–4 arguments, group them into a struct, or use functional options (opts ...Option) for a constructor that will grow; a new option is backward-compatible, a new positional argument is not.

  2. Declare complex arguments as named locals before the call instead of nesting constructor calls inline:

    sentAt := time.Now().Add(-24 * time.Hour)
    priority := Priority(3)
    client.Send(NewMessage(sender, recipient, sentAt, priority))
    
  3. Guard and return early; the happy path stays at the bottom, unindented, with no else after a return. Use switch over if/else if chains.

  4. Use pointers for mutation and measurably large structs, values for small immutable types. Never use *T to mean "might not be set"; that is Option[T].


Naming and Comments

Name functions by what they return or do (ParseConfig, IsExpired) and booleans as predicates (canRetry). Abbreviate only by Go convention (ctx, err, id, r, w).

~/.claude/rules/comments.md decides what earns a comment. It is the authority and this skill does not restate or soften it. Read it before editing a file and apply it as written, including its line cap and its exported-identifiers-only rule for doc comments. internal/ is not public API. When reviewing Go code for comment quality, use the clean-comments skill. Do not instruct it to match the file's existing comment density.


Tooling

Run gofmt, goimports, go vet ./... and golangci-lint run before finishing. Leave mechanical rules to the linter rather than restating them here. Never add //nolint to existing violations: fix them, or leave the rule off until they are fixed.


See Also

SkillWhen to reach for it
go-testingHow tests are written: assertions, doubles, tables, test databases
tddTDD cycle, red-green-refactor, writing the test first
clean-commentsAudit and remove explanatory comments across Go code
improve-codebase-architectureIdentify structural improvements, shallow modules
simplifyReview changed code for quality, reuse, and efficiency after implementation

Comments

Markdown supported