# Way Go Style

> Guide for writing idiomatic, effective, and standard Go code. Use this skill when writing, refactoring, or reviewing Go code to ensure adherence to established conventions and best practices.

- Skill: `majiayu000/way-go-style` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add majiayu000/way-go-style`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/way-go-style/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/way-go-style

---


# Way Go Style

## Project Setup (AGENTS.md)

Go projects MUST include this skill's **Way Specific Conventions** in their `AGENTS.md` file to ensure compliance.

1.  **Reference this skill**: Under "Local Skills".
2.  **Copy Conventions**: Copy the **Way Specific Conventions** section below into `AGENTS.md` under "Key Conventions".

## Way Specific Conventions

- **Testing**: Use standard `testing` and `github.com/google/go-cmp/cmp` **only**. No frameworks (Testify, Ginkgo, etc.).
- **Linting**: Run `GolangCI-Lint` v2. Configure via project-specific `.golangci.yml`.
- **Build**: Use `way-magefile` skill.
- **Encore**: Use `encore-go-*` skills. Encore conventions (e.g., globals) take precedence.

## Overview

This skill provides a condensed reference for writing high-quality Go code, synthesizing advice from "Effective Go", Google's "Code Review Comments", and other authoritative sources. It focuses on idiomatic usage, correctness, and maintainability.

## Effective Go Idioms

Critical idioms from [Effective Go](references/effective_go.html).

### Control Flow & Error Handling
- **Defer Evaluation:** Arguments to deferred functions are evaluated **immediately** at the call site (not at execution).
- **Init Scope:** Use `if err := f(); err != nil` to restrict variable scope.
- **Switch:** Use tagless `switch { case condition: ... }` instead of long `if-else` chains.
- **Internal Panic/Recover:** Use `panic` to simplify deep error handling in complex internal code (e.g., parsers), but **always** `recover` at the package boundary to return a standard `error`.

### Types & Interfaces
- **Functional Adapters:** Define methods on function types (e.g., `type MyFunc func()`) to satisfy interfaces. See `http.HandlerFunc`.
- **Interface Verification:** Use a global blank assignment to ensure a type satisfies an interface at compile time: `var _ Interface = (*Type)(nil)`.

## Google Style Decisions & Best Practices

Key decisions from the [Google Go Style Guide](references/google/index.md) and [Code Review Comments](references/CodeReviewComments.md).

### Core Principles
- **Clarity:** "Clear to the reader" is priority #1. Explain *why*, not just *what*.
- **Simplicity:** "Least Mechanism". Prefer core constructs (slices, maps) over complex abstractions.
- **Concision:** High signal-to-noise ratio. Avoid boilerplate.

### Naming & Structure
- **Packages:** Single-word, lowercase (e.g., `task`, not `task_manager`). **Avoid** `util`, `common`.
- **Receivers:** 1-2 letter abbreviations (e.g., `c` for `Client`). **NEVER** use `me`, `this`, `self`.
- **Constants:** Always `MixedCaps` (e.g., `MaxLength`), even if exported. **NEVER** `MAX_LENGTH`.
- **Getters:** `Owner()` (not `GetOwner`).
- **Interfaces:** One-method interfaces -> `Method` + `-er` (e.g., `Reader`). Define in the **consumer** package. Keep them small.

### Functions & Methods
- **Receiver Type:**
  - **Pointer (`*T`):** If mutating, contains `sync.Mutex`, or large struct.
  - **Value (`T`):** Maps, channels, functions, small immutable structs.
  - **Consistency:** Prefer all pointers or all values for a type's methods.
- **Pass Values:** Don't pass pointers to small types (`*string`, `*int`) just to save memory.
- **Synchronous:** Prefer synchronous APIs. Let the caller decide to use goroutines.
- **Must Functions:** `MustXYZ` panic on failure. Use **only** for package-level init or test helpers.

### Error Handling
- **Flow:** Handle errors immediately (`if err != nil { return err }`). Keep "happy path" unindented. Avoid `else`.
- **Structure:** Use `%w` with `fmt.Errorf` to wrap errors for programmatic inspection (`errors.Is`).
- **Panics:** **Never** panic in libraries. Return errors. `log.Fatal` is okay in `main`.
- **Strings:** Lowercase, no punctuation (e.g., `fmt.Errorf("something bad")`) for easy embedding.

### Concurrency
- **Lifetimes:** Never start a goroutine without knowing how it stops.
- **Context:** Always first arg `ctx context.Context`. **Never** store in structs.
- **Copying:** **Do not copy** structs with `sync.Mutex` or `bytes.Buffer`.

### Testing
- **Framework:** Use `testing` package. No assertion libraries (use `cmp` for diffs).
- **Helpers:** Mark setup/teardown functions with `t.Helper()`.
- **Failure Messages:** `YourFunc(%v) = %v, want %v`. (Got before Want).
- **Table-Driven:** Use field names in struct literals for clarity.
- **Subtests:** Use `t.Run()` for clear scope and filtering. Avoid slashes in names.

### Global State & Init
- **Avoid Globals:** Libraries should not rely on package-level vars. Allow clients to instantiate (`New()`).
- **Initialization:** Use `:=` for non-zero values. Use `var t []T` (nil) for empty slices.
- **Imports:** Group order: Stdlib, Project/Vendor, Side-effects (`_`). No `.` imports.

## Practical Go Cheat Sheet

Best practices for maintainable Go from **Dave Cheney's** [Practical Go](references/dave-cheney-practical-go.md).

### Guiding Principles
- **Simplicity, Readability, Productivity:** The core values. Clarity > Brevity.
- **Identifiers:** Choose for clarity. Length proportional to scope/lifespan. Don't include type in name (e.g., `usersMap` -> `users`).

### Design & Structure
- **Package Names:** Name for what it *provides* (e.g., `http`), not what it contains. Avoid `util`, `common`.
- **Project Structure:** Prefer fewer, larger packages. Arrange files by import dependency.
- **API Design:** Hard to misuse. Avoid multiple params of same type. Avoid `nil` params.
- **Interfaces:** Let functions define behavior they require (e.g., take `io.Writer` not `*os.File`).
- **Zero Value:** Make structs useful without explicit initialization (e.g., `sync.Mutex`, `bytes.Buffer`).

### Concurrency & Errors
- **Concurrency:** Leave it to the caller. Never start a goroutine without knowing when/how it stops.
- **Errors:** Eliminate error handling by eliminating errors (e.g., `bufio.Scanner`). Handle errors once (don't log AND return).
- **Return Early:** Use guard clauses. Keep the "happy path" left-aligned.

## Available References

Detailed documentation available in the `references/` directory:

- **[Effective Go](references/effective_go.html):** (HTML) The foundational guide to idiomatic Go.
- **[Code Review Comments](references/CodeReviewComments.md):** Common comments made during Go code reviews at Google.
- **[Google Style Guide](references/google/index.md):** Complete set of Google's Go style documents.
  - [Guide](references/google/guide.md): Core guidelines.
  - [Decisions](references/google/decisions.md): Normative style decisions.
  - [Best Practices](references/google/best-practices.md): Evolving guidance.
- **[Practical Go](references/dave-cheney-practical-go.md):** **Dave Cheney's** advice on writing maintainable Go programs.
