golang
Use when building Go backend services, implementing goroutines/channels, handling errors idiomatically, writing tests with testify, or following Go best practices for APIs/CLI tools.
Install
mkdir -p .claude/skills/golang && curl -L -o skill.zip "https://mcp.directory/api/skills/download/9102" && unzip -o skill.zip -d .claude/skills/golang && rm skill.zipInstalls to .claude/skills/golang
About this skill
Go Development Best Practices
Version: 2.0.0 Purpose: Comprehensive Go development patterns covering idioms, error handling, concurrency, testing, and quality Scope: Backend development with Go - API services, CLI tools, system software Prerequisites: Basic Go syntax knowledge
Overview
Go (Golang) is designed for simplicity, explicit error handling, and safe concurrent programming. This skill covers production-ready patterns validated by the Go community, official documentation, and industry standards (Uber Engineering, Google).
Core Philosophy:
- Simplicity: "Clear is better than clever" - favor readable code over abstractions
- Explicit over implicit: No exceptions, no hidden control flow, visible errors
- Composition over inheritance: Interfaces and embedding, not class hierarchies
- Built-in concurrency: Goroutines and channels as first-class primitives
- Tooling-first: Format, vet, test, and benchmark built into the language
Key Design Principles:
- Small interfaces (1-3 methods ideal)
- Consumer-side interface placement
- Error values, not exceptions
- Happy path at left margin
- Goroutines must have explicit termination
1. Idiomatic Go Patterns
1.1 Naming Conventions
Package Names:
// ✅ GOOD: Package names are single lowercase identifiers
// Import path: "net/url" → package name: url
// Import path: "encoding/json" → package name: json
package url // from "net/url"
package json // from "encoding/json"
package strings
// ❌ BAD
package urls // No plural
package encodingjson // Don't smash words together
package stringutils // Too verbose
Getters and Setters:
type Account struct {
balance int
}
// ✅ GOOD: No "Get" prefix
func (a *Account) Balance() int {
return a.balance
}
func (a *Account) SetBalance(amount int) {
a.balance = amount
}
// ❌ BAD: Java-style getters
func (a *Account) GetBalance() int {
return a.balance
}
Error Variables:
// Exported sentinel errors (capitalized)
var ErrNotFound = errors.New("not found")
var ErrTimeout = errors.New("timeout")
// Unexported internal errors (lowercase)
var errInternal = errors.New("internal error")
Interface Naming:
// ✅ GOOD: Short, descriptive
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
// ❌ BAD: Verbose or unclear
type DataReader interface { ... }
type IReader interface { ... } // No "I" prefix
1.2 Interface Design - "The Bigger the Interface, the Weaker the Abstraction"
Core Principle: Small, consumer-side interfaces provide maximum flexibility.
Single-Method Interfaces (Ideal):
// Standard library examples
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
// Compose interfaces
type ReadCloser interface {
Reader
Closer
}
Consumer-Side Interface Placement:
// ❌ WRONG: Producer defines interface
package store
type CustomerStorage interface {
StoreCustomer(Customer) error
GetCustomer(string) (Customer, error)
UpdateCustomer(Customer) error
// 10+ methods...
}
type PostgresStore struct {}
func (s *PostgresStore) StoreCustomer(...) { ... }
// ✅ CORRECT: Consumer defines what it needs
package client
type customerGetter interface {
GetCustomer(string) (store.Customer, error)
}
func ProcessCustomer(cg customerGetter) {
customer, _ := cg.GetCustomer("123")
// Only depends on GetCustomer method
}
Return Concrete Types, Accept Interfaces (Postel's Law):
// ✅ GOOD
func NewStore() *PostgresStore {
return &PostgresStore{}
}
func Process(storage CustomerStorage) error {
// Accepts interface
}
// ❌ BAD: Returning interface
func NewStore() CustomerStorage {
return &PostgresStore{}
}
When to Create Interfaces:
- Multiple implementations exist or are planned
- Need for testing (mocking dependencies)
- Decoupling packages
- NOT for: Single implementation with no testing need
1.3 Happy Path Left, Early Returns
Core Principle: Align success path to left margin, handle errors first.
// ❌ BAD: Deep nesting
func join(s1, s2 string, max int) (string, error) {
if s1 == "" {
return "", errors.New("s1 is empty")
} else {
if s2 == "" {
return "", errors.New("s2 is empty")
} else {
concat, err := concatenate(s1, s2)
if err != nil {
return "", err
} else {
if len(concat) > max {
return concat[:max], nil
} else {
return concat, nil
}
}
}
}
}
// ✅ GOOD: Happy path aligned left
func join(s1, s2 string, max int) (string, error) {
if s1 == "" {
return "", errors.New("s1 is empty")
}
if s2 == "" {
return "", errors.New("s2 is empty")
}
concat, err := concatenate(s1, s2)
if err != nil {
return "", err
}
if len(concat) > max {
return concat[:max], nil
}
return concat, nil
}
Guidelines:
- Maximum 3-4 levels of nesting
- Omit
elseblocks whenifreturns - Handle errors immediately
- Keep normal flow at lowest indentation
1.4 Composition Over Inheritance
Type Embedding (Struct Composition):
// Embedding for method promotion
type Logger struct {
*log.Logger
prefix string
}
func NewLogger(prefix string) *Logger {
return &Logger{
Logger: log.New(os.Stdout, "", 0),
prefix: prefix,
}
}
// Logger methods automatically available
logger := NewLogger("APP")
logger.Println("message") // Calls embedded log.Logger.Println
Interface Composition:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
// Compose interfaces
type ReadCloser interface {
Reader
Closer
}
Warning: Avoid embedding in public APIs:
// ❌ BAD: Exposes implementation details
type MyHandler struct {
http.Handler // Leaks all Handler methods
}
// ✅ GOOD: Explicit delegation
type MyHandler struct {
handler http.Handler
}
func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Custom logic
h.handler.ServeHTTP(w, r)
}
1.5 Key Go Idioms
Defer for Cleanup:
func processFile(path string) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close() // Guaranteed cleanup
// Multiple returns, all close file
if condition {
return nil // File closed
}
return process(f) // File closed
}
// Mutex pattern
func (c *Counter) Increment() {
c.mu.Lock()
defer c.mu.Unlock()
c.value++ // All paths unlock
}
Critical Rule: Call defer AFTER checking error:
// ❌ WRONG
defer f.Close() // f is nil if Open failed
f, err := os.Open(path)
// ✅ CORRECT
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
Multiple Return Values:
// (value, error) - Standard error handling
func GetUser(id string) (*User, error) {
// ...
}
// (value, bool) - "comma ok" idiom
value, ok := myMap[key]
if !ok {
// key not found
}
result, ok := someValue.(TargetType)
if !ok {
// type assertion failed
}
data, ok := <-channel
if !ok {
// channel closed
}
Blank Identifier _:
// Ignore unwanted values
_, err := os.Open(filename)
// Compile-time interface check
var _ http.Handler = (*MyHandler)(nil)
// Import for side effects
import _ "net/http/pprof"
Useful Zero Values:
// sync.Mutex - ready to use
var mu sync.Mutex
mu.Lock() // Works immediately
// bytes.Buffer - valid empty buffer
var buf bytes.Buffer
buf.WriteString("hello") // No initialization needed
// Slices - safe to read
var s []int
fmt.Println(len(s)) // 0 (safe)
2. Error Handling
2.1 Error Wrapping with %w (Go 1.13+)
Core Pattern: Wrap errors with context using fmt.Errorf and %w.
func processFile(path string) error {
file, err := os.Open(path)
if err != nil {
// Wrap with context using %w
return fmt.Errorf("failed to open file %s: %w", path, err)
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read file %s: %w", path, err)
}
return processData(data)
}
// Result when error bubbles up:
// "failed to initialize: failed to open file config.json: open config.json: no such file or directory"
Checking Wrapped Errors:
// errors.Is - Check for specific error in chain
if errors.Is(err, os.ErrNotExist) {
fmt.Println("File doesn't exist")
}
// errors.As - Extract specific error type
var pathErr *os.PathError
if errors.As(err, &pathErr) {
fmt.Printf("Path error on: %s\n", pathErr.Path)
}
Critical: Use %w, NOT %v:
// ❌ WRONG: Breaks error chain
return fmt.Errorf("failed: %v", err)
// ✅ CORRECT: Preserves chain
return fmt.Errorf("failed: %w", err)
2.2 Sentinel Errors vs Custom Error Types
Sentinel Errors (Package-Level Variables):
package db
var (
ErrConnectionFailed = errors.New("database connection failed")
ErrRecordNotFound = errors.New("record not found")
ErrDuplicateKey = errors.New("duplicate key violation")
)
func GetUser(id int) (*User, error) {
// ...
if notFound {
return nil, ErrRecordNotFound
}
return user, nil
}
// Caller checks with errors.Is
user, err := db.GetUser(123)
if errors.Is(err, db.ErrRecordNotFound) {
// Handle not found
}
Custom Error Types (Rich Context):
type ValidationError struct {
Field string
Value interface{}
Message string
}
fun
---
*Content truncated.*
More by MadAppGang
View all skills by MadAppGang →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
pdf-to-markdown
aliceisjustplaying
Convert entire PDF documents to clean, structured Markdown for full context loading. Use this skill when the user wants to extract ALL text from a PDF into context (not grep/search), when discussing or analyzing PDF content in full, when the user mentions "load the whole PDF", "bring the PDF into context", "read the entire PDF", or when partial extraction/grepping would miss important context. This is the preferred method for PDF text extraction over page-by-page or grep approaches.
Related MCP Servers
Browse all serversUse Firebase to integrate Firebase Authentication, Firestore, and Storage for seamless backend services in your apps.
TypeScript framework for building MCP servers with auth, storage, OpenTelemetry, and support for Bun/Node/Cloudflare Wor
MCP Advisor helps you discover and understand MCP services quickly with natural language queries and advanced semantic s
Integrate TomTom's APIs for advanced location-aware apps with maps, routing, geocoding, and traffic—an alternative to Go
Pica is automated workflow software for business process automation, integrating actions across services via a unified i
Unlock seamless Figma to code: streamline Figma to HTML with Framelink MCP Server for fast, accurate design-to-code work
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.