ワンクリックで
programming-go
Best practices when developing in Go codebases
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Best practices when developing in Go codebases
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | programming-go |
| description | Best practices when developing in Go codebases |
When the empty interface is genuinely needed, spell it any, never interface{}. (But prefer a concrete type — see Types and configuration.)
Use the - tag when marshalling JSON should omit a field. Use this for private data on a field that's meant to be excluded from an API response.
Use the Go 1.22 syntax for for loops:
Write this:
for i := range 10 {
fmt.Println(i+1)
}
NOT THIS:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
any and map[string]any in public or cross-package types when a more concrete type is possible. If an upstream JSON schema is still loose, define named wrapper types so the shape carries domain meaning.switch exhaustiveness checks catch missing cases.new(false) for bool pointers.github.com/urfave/cli/v3 instead of the stdlib flag package when adding new commands or binaries in this repo.urfave/cli commands:
Arguments and Destination. Don't manually pull required args out of cmd.Args() inside Action.Destination fields from cmd.Args(). Account for the parser lifecycle instead, and validate those destinations after argument parsing.Config with its defaults in one place, then use the same field for both the flag's Value and Destination.Before hook. Keep Action focused on final validation and execution.HasAgentName, for validation checks that describe config state.Unwrap/Is support so callers can inspect semantics.net.SplitHostPort for host and port handling instead of ad hoc string splitting, especially where IPv6 is possible.errgroup over hand-rolled goroutine synchronization when concurrent work needs error propagation.WaitGroup.Go method to add goroutines to a waitgroup. It takes the place of the go keyword:wg.Go(func() {
// your goroutine code here
})
The implementation is just a wrapper around this:
func (wg *WaitGroup) Go(f func()) {
wg.Add(1)
go func() {
defer wg.Done()
f()
}()
}
log/slog for new structured logs. Prefer context-aware calls and structured attributes such as slog.Any("err", err) over custom log writers or interpolated error strings.context.WithTimeoutCause(ctx, d, cause) (Go 1.21+) rather than context.WithTimeout, and read context.Cause(ctx) when a deadline fires. That turns a bare context deadline exceeded into an error that names which operation timed out and how long its budget was. The cause can be a sentinel you can errors.Is against to tell your own timeout apart from a parent's.http.Server.Shutdown(ctx) with a bounded context for teardown instead of an abrupt Close when graceful shutdown is possible.Write unless the type intentionally behaves like an io.Writer. Prefer domain verbs such as Record, Render, or WriteProfile.Good package names are short and clear. They are lower case, with no under_scores or mixedCaps. They are often simple nouns, such as:
The style of names typical of another language might not be idiomatic in a Go program. Here are two examples of names that might be good style in other languages but do not fit well in Go:
Abbreviate judiciously. Package names may be abbreviated when the abbreviation is familiar to the programmer. Widely-used packages often have compressed names:
On the other hand, if abbreviating a package name makes it ambiguous or unclear, don’t do it.
Similarly, the function to make new instances of ring.Ring — which is the definition of a constructor in Go—would normally be called NewRing, but since Ring is the only type exported by the package, and since the package is called ring, it's called just New, which clients of the package see as ring.New. Use the package structure to help you choose good names.
Another short example is once.Do; once.Do(setup) reads well and would not be improved by writing once.DoOrWaitUntilDone(setup). Long names don't automatically make things more readable. A helpful doc comment can often be more valuable than an extra long name.
Don’t steal good names from the user. Avoid giving a package a name that is commonly used in client code. For example, the buffered I/O package is called bufio, not buf, since buf is a good variable name for a buffer.
embed for non-trivial test inputs — TOML, SQL, JSON, request/response bodies. Avoid large inline fixture strings in test files.*_test.go helper files when they obscure the tests. Keep the test cases themselves near the top and easy to scan.assert* helpers that hide the expected behavior. Keep checks inline and left-aligned when that makes the happy path easier to scan.cmp.Diff for structured comparisons instead of several hand-written field checks when the diff will be easier to diagnose.errors.Is or errors.As with exported sentinel errors or concrete error types, especially when tests live outside the package.testing.TB, not only *testing.T, so they work for tests, benchmarks, and fuzz targets.package deployer_test, when tests don't need unexported internals. This keeps package boundaries honest.testing/synctest when time must advance.t.Fatal or FailNow from goroutines or HTTP handler callbacks. Report with t.Error and return, or signal the test goroutine.just recipes. Don't add shell scripts that only wrap go run — add a recipe instead.Best practices when developing in Crystal codebases
Write an Architecture Decision Record (ADR) — lead with the decision, give neutral context, and state consequences both ways. Use when recording an architectural or technical decision, documenting why a choice was made, or capturing tradeoffs for future maintainers.
Write essays, blog posts, newsletters, and opinion pieces in a personal first-person voice — concrete cold open, argument by historical analogy, deliberate sentence rhythm, aphoristic kicker. Use when drafting or editing personal essays, blog posts, op-eds, newsletter issues, or any first-person long-form meant to persuade or reflect.
Write an RFC or design doc — summary-first, with goals/non-goals, real alternatives, drawbacks, and open questions. Use when proposing a technical change for review, writing a design doc, or documenting a system or feature proposal before building it.
Write clear technical documents — design docs, PR descriptions, proposals, postmortems — that lead with the decision and ground every claim in specifics. Use when drafting or editing workplace technical writing where a reader must act or later understand why. For the specific RFC and ADR formats, use writing-rfc and writing-adr.
Python development guidelines and best practices. Use when working with Python code.