go-skills

Senior Go developer. Rocket engine included.

Add one skill — code Go like a senior with 10+ years across hundreds of production projects. Claude Code + you + go-skills = no rookie mistakes, idiomatic Go from prompt one.

Quick start

Done with one Claude Code prompt.

Paste this into Claude Code. It clones go-skills, registers it as a skill source, reloads, and confirms — about 30 seconds, no manual edits.

Install go-skills as a Claude Code skill source.

1. Clone https://github.com/amazopic/go-skills to ~/.claude/plugins/go-skills
2. Add "~/.claude/plugins/go-skills/skills" to skillSources in ~/.claude/settings.json
3. Reload settings
4. List the skills you now have access to

After install I want to code Go with senior-level patterns and the 18-chapter service-architecture methodology.

Just vibe — let Claude Code set it all up.

Set up go-skills for me — handle everything, I'll just vibe.

1. Clone https://github.com/amazopic/go-skills to ~/.claude/plugins/go-skills
2. Add "~/.claude/plugins/go-skills/skills" to skillSources in ~/.claude/settings.json
3. Reload settings and confirm the skills are live
4. Tell me in one line what you can now help with — patterns, methodology, workflows

Then ask what I'm building and start coding Go at senior level — idiomatic, race-safe, no rookie mistakes.
Start here

Already have a Go project? Point go-skills at it.

The fastest way in: a five-role team reads your codebase and returns a maturity score plus a prioritized roadmap — every item linked to the exact go-skills pattern or chapter to apply. Read-only; it never touches your code.

Using the go-skills "Project Assessment" workflow skill, assess my existing Go project.

Read the codebase under <path> and produce a maturity assessment plus a prioritized roadmap where every finding cites the specific go-skills methodology chapter or pattern to apply. Read-only — do not change any code. Then propose the first sprint.
Three pillars

Methodology · Patterns · Skills.

A reference for senior Go engineers — opinionated, source-derived, no decoration. The methodology gives you a baseline service; the patterns sharpen the parts; the skills make it all addressable from Claude Code.

Methodology

An 18-chapter playbook for building production Go services — directory layout, layered architecture, manual DI, configuration, retries, storage, transport, jobs, logging, validation, error handling, testing, build/deploy, default stack.

Patterns

52 senior-grade patterns across creational, structural, behavioral, concurrency, synchronization, messaging, stability, profiling, idiom, anti-patterns — every entry written by a senior Go consultant, with race-safe runnable examples where applicable.

Skills

Each pattern and chapter is a Claude Code skill — a markdown file with a triggerable description. Drop the repo into your skills path and it surfaces the right knowledge for the task at hand.

Inventory

By the numbers.

10
Categories
52
Patterns
18
Methodology chapters
52
Runnable examples
23
Languages
Service Methodology

A reference for building services in Go.

An anonymized, project-agnostic playbook. Read end-to-end as the canonical 930-line document, or pick a chapter-skill below.

  1. 01Principles & Layout
  2. 02Layered Architecture
  3. 03Bootstrap & DI
  4. 04Configuration
  5. 05External Connections
  6. 06Storage
  7. 07HTTP Transport
  8. 08Background Jobs
  9. 09Logging
  10. 10Validation
  11. 11Error Handling
  12. 12Testing
  13. 13Build & Deploy

Read the full canonical document →

Catalog

All patterns.

Filled cards have a body and (where applicable) a runnable example. Stubs are listed for completeness — body to be filled in a future iteration.

Workflow

filled

Project Assessment

Start here on an existing project. Five specialists — senior Go, strong-middle Go, DB architect, test/reliability, SecOps — assess independently against the catalog; the senior consolidates a maturity report; a reverse analysis culls nitpicks; you approve a prioritized roadmap where every item links to a go-skill. Read-only.

5x assess    (parallel, vs the catalog)
  -> consolidate     (one maturity report)
  -> reverse-analysis (cull generic nitpicks)
  -> ROADMAP -> your approval gate
  -> hand off to build / security flows
filled

Feature Development Flow

A trio — strong-middle Go, senior Go, DB architect — analyzes independently; the senior consolidates; the same team reverse-reviews; you approve; then they build it. Ships with a runnable orchestration script.

3x analyze   (parallel, independent)
  -> consolidate    (senior owns the merge)
  -> reverse-review  (same trio attacks it)
  -> FINAL PLAN -> your approval gate
  -> implement       (same trio, peer-reviewed)
filled

Security Code Review

Four specialists — senior Go, strong-middle Go, DB architect, senior SecOps — audit independently; the senior Go consolidates one report; a reverse analysis culls false positives and finds attack chains; you approve a prioritized remediation plan; then the team fixes it.

4x audit     (parallel, independent)
  -> consolidate     (dedup + attack chains)
  -> reverse-analysis (cull false positives,
                       verify exploitability)
  -> REMEDIATION PLAN -> your approval gate
  -> remediate        (peer-verified, regression-tested)

Concurrency

filled

Bounded Parallelism

Process N items with at most K workers concurrently.

sem := make(chan struct{}, K)
for _, item := range items {
    sem <- struct{}{}
    go func(it Item) {
        defer func(){ <-sem }()
        process(it)
    }(item)
}
filled

Generator

Goroutine emits values on a channel, returned as <-chan T.

func gen(in []int) <-chan int {
    out := make(chan int)
    go func(){
        defer close(out)
        for _, v := range in { out <- v }
    }()
    return out
}
filled

Parallelism

Scatter work across goroutines, gather results.

var wg sync.WaitGroup
for _, x := range xs {
    wg.Add(1)
    go func(v int){ defer wg.Done(); work(v) }(x)
}
wg.Wait()
filled

N-Barrier

Wait until N goroutines reach the same point.

b := NewBarrier(N)
for i := 0; i < N; i++ {
    go func(){ work(); b.Wait() }() // released only when all arrive
}
filled

Broadcast

Send the same message to all subscribers.

sub := bcast.Subscribe()
defer sub.Close()
for v := range sub.Ch() { handle(v) }
// elsewhere: bcast.Send(value)
filled

Coroutines

Cooperative goroutine pairs that yield between each other.

Generate(ctx, func(yield func(int) bool) {
    for i := 0; ; i++ {
        if !yield(i) { return } // consumer signals stop
    }
})
filled

Producer Consumer

Decouple work generation from work processing via a channel.

work := make(chan Job, 64) // bounded buffer = backpressure
go produce(ctx, work)
for j := range work { process(j) }
filled

Reactor

Single-threaded event loop dispatching to handlers.

for {
    select {
    case e := <-events: handlers[e.Kind](e)
    case <-ctx.Done(): return
    }
}

Stability

filled

Circuit Breaker

Open the circuit after N failures so the dependency can recover.

// state: closed | open | half-open
if breaker.state == "open" && time.Since(breaker.openedAt) > cooldown {
    breaker.state = "half-open"
}
if err := fn(); err != nil {
    breaker.failures++
    if breaker.failures >= threshold {
        breaker.state = "open"
    }
}
filled

Bulkhead

Isolate resource pools so one consumer cannot exhaust shared capacity.

slot := make(chan struct{}, K) // per-tenant capacity
select {
case slot <- struct{}{}:
    defer func(){ <-slot }(); do()
default:
    return ErrOverloaded // shed, never queue
}
filled

Deadline

Bound the maximum time a request can wait.

ctx, cancel := context.WithDeadline(parent, deadline)
defer cancel()
if err := dep.Call(ctx, req); errors.Is(err, context.DeadlineExceeded) {
    return ErrTimeout
}
filled

Fail-Fast

Reject early if preconditions cannot be met.

if !ready.Load()           { return ErrNotReady }
if errs := cfg.Validate(); errs != nil { return errs }
// proceed only when all preconditions hold
filled

Handshaking

Negotiate capacity between client and server before work starts.

budget, lease := srv.Negotiate(client.Capacity())
defer srv.Release(lease)
sem := make(chan struct{}, budget)
filled

Steady-State

Bound resource accumulation so the system reaches a stable equilibrium.

go janitor(ctx, time.Minute, func(){
    cache.EvictExpired()
    log.Rotate()
})

Messaging

filled

Fan-In

Multiplex several channels into one.

func merge(cs ...<-chan int) <-chan int {
    out := make(chan int)
    for _, c := range cs {
        go func(c <-chan int){
            for v := range c { out <- v }
        }(c)
    }
    return out
}
filled

Fan-Out

Distribute work from one channel to N workers.

func fanOut(in <-chan Job, n int) {
    var wg sync.WaitGroup
    wg.Add(n)
    for i := 0; i < n; i++ {
        go func(){
            defer wg.Done()
            for j := range in { process(j) }
        }()
    }
    wg.Wait()
}
filled

Publish/Subscribe

Topic-based event distribution via a broker.

bus.Subscribe("topic", func(m Msg){ /* ... */ })
bus.Publish("topic", msg)
filled

Futures & Promises

Represent the eventual result of an async computation.

f := NewFuture(func() (T, error) { return slowCall(ctx) })
v, err := f.Get(ctx) // memoized: many callers see the same value
filled

Push & Pull

Mirror Fan-Out / Fan-In with explicit pull-side semantics.

push := make(chan Job)
for i := 0; i < N; i++ { go puller(push) } // first-come wins
push <- job // load-balanced across pullers

Synchronization

filled

Semaphore

Buffered channel as a counting semaphore.

sem := make(chan struct{}, N)
sem <- struct{}{}
defer func(){ <-sem }()
filled

Mutex

sync.Mutex for exclusive access to shared state.

type Counter struct { mu sync.Mutex; n int }
func (c *Counter) Inc() {
    c.mu.Lock(); defer c.mu.Unlock()
    c.n++
}
filled

Read-Write Lock

sync.RWMutex when reads dominate writes.

mu.RLock(); v := m[k]; mu.RUnlock() // many concurrent readers
mu.Lock();  m[k] = v; mu.Unlock()    // one writer, blocks readers
filled

Monitor

Bundle state and synchronization in one type.

type Pool struct {
    mu   sync.Mutex
    free []*Conn
}
func (p *Pool) Get() *Conn { /* mu-guarded acquire */ }
filled

Condition Variable

sync.Cond for waiting on a state change.

mu := sync.Mutex{}
cond := sync.NewCond(&mu)
mu.Lock()
for !ready { cond.Wait() } // ALWAYS loop the predicate
mu.Unlock()

Idioms

filled

Functional Options

func(*T) options for ergonomic optional configuration.

type Option func(*Server)
func WithTimeout(d time.Duration) Option {
    return func(s *Server){ s.timeout = d }
}
NewServer(":8080", WithTimeout(5*time.Second))
filled

Specification

Encapsulate a predicate over an entity for reuse.

overdue := SpecFunc(func(i Invoice) bool { return i.DaysLate > 30 })
unsent  := SpecFunc(func(i Invoice) bool { return !i.IsSent })
And(overdue, unsent)(invoice) // composable predicates

Creational

filled

Builder

Step-by-step assembly of a complex object.

b := NewBuilder().WithName("x").WithSize(10).Build()
filled

Factory Method

Defer instantiation to a function.

func NewWidget(kind string) Widget {
    switch kind {
    case "a": return &A{}
    default:  return &B{}
    }
}
filled

Object Pool

Reuse expensive objects via sync.Pool.

var pool = sync.Pool{
    New: func() any { return new(Buffer) },
}
filled

Singleton

Lazy single instance via sync.Once.

var once sync.Once
var instance *T
func Get() *T {
    once.Do(func(){ instance = &T{} })
    return instance
}
filled

Abstract Factory

Family of related factories behind one interface.

type WidgetFactory interface {
    NewButton() Button
    NewMenu()   Menu
}
// MacFactory, WinFactory implement; caller picks one at runtime.
filled

Prototype

Clone an existing instance instead of constructing anew.

func (s *Shape) Clone() *Shape {
    cp := *s
    cp.Vertices = append([]Vec{}, s.Vertices...) // deep-copy slice
    return &cp
}

Structural

filled

Decorator

Wrap a value to extend behavior, preserve interface.

type Logger func(http.Handler) http.Handler
filled

Proxy

Stand-in object controls access to the real one.

func (p *Proxy) Get(k K) V {
    if v, ok := p.cache[k]; ok { return v }
    v := p.real.Get(k)
    p.cache[k] = v
    return v
}
filled

Adapter

Translate one interface to another.

type LegacyReader struct{ legacy *LegacyClient }
func (a *LegacyReader) Read(p []byte) (int, error) {
    return a.legacy.Recv(p) // adapt Recv → io.Reader
}
filled

Bridge

Decouple abstraction from implementation.

type Renderer interface{ DrawCircle(r float64) }
type Shape    struct{ r Renderer } // abstraction holds impl
func (s *Shape) Draw() { s.r.DrawCircle(1) }
filled

Composite

Treat single objects and compositions uniformly.

type Node interface{ Size() int }
type Dir  struct{ children []Node }
func (d *Dir) Size() int {
    sum := 0
    for _, c := range d.children { sum += c.Size() }
    return sum
}
filled

Facade

Front a subsystem with a simpler API.

type Auth struct{ users *UserDB; tokens *TokenStore; rate *Limiter }
func (a *Auth) Login(u, p string) (Token, error) {
    // coordinates the 3 subsystems behind one method
}
filled

Flyweight

Share intrinsic state across many instances.

var (
    mu     sync.Mutex
    glyphs = map[rune]*Glyph{}
)
func Get(r rune) *Glyph {
    mu.Lock(); defer mu.Unlock()
    if g, ok := glyphs[r]; ok { return g }
    glyphs[r] = render(r); return glyphs[r]
}

Behavioral

filled

Observer

One-to-many notification of state changes.

type Observer interface{ OnEvent(e Event) }
filled

Strategy

Select algorithm at runtime via interface.

type Sorter interface{ Sort([]int) []int }
filled

Chain of Responsibility

Pass the request along until one handler consumes it.

func Chain(hs ...Handler) Handler {
    return func(r Request) Response {
        for _, h := range hs {
            if resp := h(r); resp.Handled { return resp }
        }
        return notFound
    }
}
filled

Command

Encapsulate an action and its arguments as an object.

type Command func() error
queue := []Command{move, save, notify}
for _, c := range queue {
    if err := c(); err != nil { rollback() }
}
filled

Iterator

Sequential access to elements of an aggregate.

func gen(ctx context.Context, xs []int) <-chan int {
    out := make(chan int)
    go func() {
        defer close(out)
        for _, v := range xs {
            select { case out <- v: case <-ctx.Done(): return }
        }
    }()
    return out
}
filled

Mediator

Centralize complex peer-to-peer communication.

type Bus struct{ peers map[string]chan Msg }
func (b *Bus) Send(to string, m Msg) { b.peers[to] <- m }
// peers don't know each other; only the bus
filled

Memento

Capture and restore an object's state.

type Memento struct{ state []byte }
func (e *Editor) Snapshot() Memento { return Memento{state: clone(e.buf)} }
func (e *Editor) Restore(m Memento) { e.buf = m.state }
filled

State

Object behavior changes with internal state.

type State interface{ Next(in Event) State }
func (m *Machine) Step(e Event) { m.state = m.state.Next(e) }
// each State implements its own transitions
filled

Template Method

Skeleton in base, overridable steps in subtypes.

type Importer struct{ Hooks ImportHooks }
func (im *Importer) Run() {
    im.Hooks.Open(); defer im.Hooks.Close()
    for r := range im.Hooks.Read() { im.Hooks.Process(r) }
}
filled

Visitor

External operation over an object hierarchy.

// Idiomatic Go: a type switch
switch x := node.(type) {
case *File: countFile(x)
case *Dir:  countDir(x)
}
filled

Registry

Global lookup table for shared singletons.

var drivers = NewRegistry[Driver]()
func init(){ drivers.Register("postgres", &PgDriver{}) }
drv, ok := drivers.Get("postgres")

Profiling

filled

Timing

Defer-based per-call latency log.

defer func(t time.Time){
    log.Printf("took %v", time.Since(t))
}(time.Now())

Anti-Patterns

filled

Cascading Failures

Failure of one component triggers further failures downstream.

// ❌ no timeout, no bulkhead, retries-on-error → cascade
resp, err := client.Get(downstream) // hang here blocks caller's goroutine
for err != nil { resp, err = client.Get(downstream) } // amplifies load
Specimens

Three patterns, in full.

Functional Options

The idiomatic Go way to pass optional configuration to a constructor.

type Server struct {
    addr    string
    timeout time.Duration
}

type Option func(*Server)

func WithTimeout(d time.Duration) Option {
    return func(s *Server) { s.timeout = d }
}

func NewServer(addr string, opts ...Option) *Server {
    s := &Server{addr: addr, timeout: 30 * time.Second}
    for _, opt := range opts {
        opt(s)
    }
    return s
}

// usage
srv := NewServer(":8080", WithTimeout(5 * time.Second))

Circuit Breaker

Fail fast for an unreliable downstream so it has time to recover.

type Breaker struct {
    failures   int
    state      string // "closed" | "open" | "half-open"
    openedAt   time.Time
    threshold  int
    cooldown   time.Duration
    mu         sync.Mutex
}

func (b *Breaker) Call(fn func() error) error {
    b.mu.Lock()
    if b.state == "open" && time.Since(b.openedAt) > b.cooldown {
        b.state = "half-open"
    }
    if b.state == "open" {
        b.mu.Unlock()
        return errors.New("circuit open")
    }
    b.mu.Unlock()

    err := fn()
    b.mu.Lock(); defer b.mu.Unlock()
    if err != nil {
        b.failures++
        if b.failures >= b.threshold { b.state = "open"; b.openedAt = time.Now() }
        return err
    }
    b.failures = 0
    b.state = "closed"
    return nil
}

Fan-Out

Distribute work from a single channel across N worker goroutines.

func fanOut(in <-chan Job, n int) {
    var wg sync.WaitGroup
    wg.Add(n)
    for i := 0; i < n; i++ {
        go func() {
            defer wg.Done()
            for j := range in {
                process(j)
            }
        }()
    }
    wg.Wait()
}
Install

Use as Claude Code skills.

Drop the repo into your skills path. Claude Code will surface skills from this repo when their description matches your task.

git clone https://github.com/amazopic/go-skills.git ~/.claude/plugins/go-skills

Then add to ~/.claude/settings.json:

{
  "skillSources": [
    "~/.claude/plugins/go-skills/skills"
  ]
}

Restart Claude Code.

An MCP server that exposes the same content programmatically is on the roadmap — see below.

Roadmap

What's next.

  • Translate all 52 skill bodies into the 11 secondary languages (currently English-only).
  • MCP server: expose tools.list_patterns, tools.get_pattern, and methodology chapters as resources.
  • Translate methodology and pattern bodies (currently English-only) into the 12 secondary languages.
  • CI: markdown-link-check, go test ./examples/..., Lighthouse-CI, JSON-LD validation, README parity.
  • Slash command /go-skill <pattern> to inject a pattern into Claude Code context on demand.
FAQ

Frequently asked.

Why build this when go-patterns already exists on GitHub?
go-skills consolidates two upstream archives (theory + runnable code), adds a service-architecture methodology, and packages everything as Claude Code-compatible skills with rich frontmatter — so your editor surfaces the right pattern automatically.
Are the patterns idiomatic Go or GoF translations?
Both. Concurrency, messaging, stability, profiling, idiom — these are Go-native. Creational/structural/behavioral are GoF translated to Go with idiomatic adjustments (e.g., functional options replacing Builder where it makes sense).
How were the patterns vetted?
Every one of the 52 entries was written by a senior Go consultant — idiomatic Go, opinionated guidance on when the GoF shape fits and when a Go-native alternative wins. All 52 example packages pass go test -race; no upstream bugs left behind.
Will the examples run on my machine?
Yes — one shared go.mod at examples/. Run cd examples && go test ./.... Go 1.22+.
When will the MCP server land?
A future iteration. The mcp/ folder holds a roadmap-only README in v1; the protocol surface is sketched there.
Why Linear's design system?
Linear's near-black + single-accent aesthetic matches the content — dense, technical, no decoration. Editorial New + Geist Mono carry the typography.
License?
MIT. Use, fork, redistribute freely.
Does this support the methodology in non-English?
README is translated to 23 languages. Pattern bodies and methodology chapters are English-only in v1; localization is on the roadmap.