go
Guides your agent to write efficient and readable Go code. It helps build network services and distributed systems quickly.
What it does
This guide teaches best practices for writing code in the Go programming language. It shows how to handle errors, use lists (slices) and dictionaries (maps), and manage concurrent tasks (goroutines and channels) efficiently and clearly.
When to use it
- ✓When learning to program in Go.
- ✓When reviewing or improving existing Go code.
- ✓When encountering common Go errors.
Example of what to ask your AI
“How can I handle errors correctly in Go?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
The guide compares 'bad' code examples with 'good' ones to illustrate recommended practices. It explains why one approach is better than another, focusing on clarity and efficiency.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add sickn33/agentic-awesome-skills --skill goOr download just the file:
curl -L https://raw.githubusercontent.com/sickn33/agentic-awesome-skills/main/plugins/agentic-awesome-skills-claude/skills/super-code/go/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
Go: Idiomatic Efficiency Reference
When to Use
- Use this skill when the task matches this description: Language-specific super-code guidelines for go.
Table of Contents
- Error Handling
- Slices & Maps
- Goroutines & Channels
- Structs & Interfaces
- Functions & Closures
- Anti-patterns specific to Go
1. Error Handling {#errors}
// ❌ Ignoring errors
result, _ := os.Open(path)
// ✅ — always handle; only use _ when error is provably irrelevant
result, err := os.Open(path)
if err != nil {
return fmt.Errorf("open %s: %w", path, err)
}
// ❌ Redundant error variable
err := doA()
if err != nil { return err }
err = doB()
if err != nil { return err }
// ✅ — each :=/: is fine; this is idiomatic Go. Don't try to "fix" it.
// What you CAN simplify: collapsing to one-liners where the if body is a single return
if err := doA(); err != nil { return err }
if err := doB(); err != nil { return err }
// ❌ Custom error type with no added value
type MyError struct{ msg string }
func (e MyError) Error() string { return e.msg }
// ✅ — use errors.New or fmt.Errorf unless callers need to inspect type
var ErrNotFound = errors.New("not found")
return fmt.Errorf("lookup %q: %w", key, ErrNotFound)
Wrap errors with %w (not %v) so callers can use errors.Is / errors.As.
2. Slices & Maps {#slices}
// ❌ Growing a slice without pre-allocation when size is known
var result []string
for _, item := range items {
result = append(result, item.Name)
}
// ✅
result := make([]string, 0, len(items))
for _, item := range items {
result = append(result, item.Name)
}
// ❌ Manual existence check before map write
if _, ok := m[key]; !ok {
m[key] = []string{}
}
m[key] = append(m[key], value)
// ✅ — append to nil slice is valid Go
m[key] = append(m[key], value)
// ❌ Copying a map by assignment (copies reference)
copy := original
// ✅
copy := make(map[K]V, len(original))
for k, v := range original { copy[k] = v }
3. Goroutines & Channels {#concurrency}
// ❌ Fire-and-forget goroutine with no lifecycle
go doWork()
// ✅ — use errgroup or WaitGroup to track completion
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
doWork()
}()
wg.Wait()
// ❌ Unbuffered channel causing unnecessary goroutine block
ch := make(chan Result)
go func() { ch <- compute() }()
result := <-ch
// ✅ — for single-result, buffered channel avoids goroutine leak if receiver exits early
ch := make(chan Result, 1)
go func() { ch <- compute() }()
result := <-ch
// ❌ select with a busy-wait default
for {
select {
case v := <-ch:
process(v)
default:
// spin
}
}
// ✅ — blocking select unless you genuinely need non-blocking
for v := range ch {
process(v)
}
Use golang.org/x/sync/errgroup for fan-out with error collection.
4. Structs & Interfaces {#structs}
// ❌ Large interface
type Storage interface {
Get(key string) ([]byte, error)
Set(key string, val []byte) error
Delete(key string) error
List(prefix string) ([]string, error)
// ... 10 more methods
}
// ✅ — small, composable interfaces
type Getter interface { Get(key string) ([]byte, error) }
type Setter interface { Set(key string, val []byte) error }
type Storage interface { Getter; Setter }
// ❌ Returning concrete struct from constructor (ties callers to implementation)
func NewStore() *RedisStore { ... }
// ✅ — return interface when you have or anticipate multiple implementations
func NewStore() Storage { return &RedisStore{...} }
// ❌ Pointer receiver for tiny value types
func (p *Point) X() float64 { return p.x }
// ✅ — value receiver for small immutable types
func (p Point) X() float64 { return p.x }
Rule: pointer receiver when method mutates state OR struct is large (>3 fields of non-trivial size). Value receiver otherwise.
5. Functions & Closures {#functions}
// ❌ Named return values used just to avoid a variable declaration
func divide(a, b float64) (result float64, err error) {
result = a / b
return
}
// ✅ — named returns are worth it only for deferred mutation or documentation
func divide(a, b float64) (float64, error) {
if b == 0 { return 0, errors.New("division by zero") }
return a / b, nil
}
…
FAQ
What are 'goroutines' and 'channels'?
They are Go's tools for running multiple tasks at the same time (goroutines) and for those tasks to communicate safely (channels).
Why is it important to 'wrap' errors with `%w`?
Using `%w` allows the code receiving the error to check if it originated from a specific error, using functions like `errors.Is` or `errors.As`.
What are 'anti-patterns'?
These are programming practices that, while they might work, often lead to more confusing, inefficient, or error-prone code. The guide shows how to avoid them in Go.
Details
Original description by the author
Language-specific super-code guidelines for go.
Popularity
- GitHub stars
- 48k
- Ranking position
- #4278
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
00-andruia-consultant
Helps your agent start or improve AI projects. It analyzes code, suggests tools, and creates action plans in Spanish.
sickn33/agentic-awesome-skills
007
Lets your agent perform security audits and threat modeling. It's useful for protecting projects against attacks and vulnerabilities.
sickn33/agentic-awesome-skills
10-andruia-skill-smith
Helps your agent create or improve AI tools. It defines how tools work, writes documentation, and validates the structure.
sickn33/agentic-awesome-skills
20-andruia-niche-intelligence
Lets your agent create a summary about a specific industry. It's useful for understanding the context, rules, usage patterns, and risks of a project, using reliable sources.
sickn33/agentic-awesome-skills
Similar skills
benchmark-optimization-loop
Has your agent improve something's speed in a measured way. It tests multiple versions and chooses the fastest one that still works correctly.
affaan-m/ECC
change-impact
Helps your agent analyze the impact of code changes before making them. It compares the planned vs. actual results afterward, covering paths, data, tests, and documentation. Useful for risky or system-wide changes.
affaan-m/ECC
click-path-audit
Lets your agent trace all user buttons and interactions to find bugs. It finds issues where functions seem to work alone but fail together. Useful when bugs persist even after debugging.
affaan-m/ECC