Claude Code Plugins

Community-maintained marketplace

Feedback

This skill should be used when the user asks to "write go", "golang", "go.mod", "go module", "go test", "go build", or works with Go language development. Provides comprehensive Go ecosystem patterns and best practices.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name Go Ecosystem
description This skill should be used when the user asks to "write go", "golang", "go.mod", "go module", "go test", "go build", or works with Go language development. Provides comprehensive Go ecosystem patterns and best practices.
version 0.2.0
Provide comprehensive patterns for Go language development, modules, testing, and idiomatic coding practices. Read - Analyze go.mod and Go source files Edit - Modify Go code and module configuration Bash - Run go build, go test, go mod commands mcp__context7__get-library-docs - Fetch latest Go documentation Errors are values, not exceptions; handle explicitly at each call site with if err != nil Accept interfaces, return concrete types; define interfaces where used, not implemented Use goroutines for concurrency, channels for communication, context.Context for cancellation Zero values are meaningful (0, "", nil, false); design types so zero value is useful Lowercase, single-word names. No underscores or mixedCaps. package httputil PascalCase for exported (public) identifiers. func ReadFile() type Handler var MaxRetries camelCase for unexported (private) identifiers. func parseConfig() type handler var maxRetries Single-method interfaces: method name + "er" suffix. Reader, Writer, Closer, Stringer, Handler Keep acronyms uppercase: URL, HTTP, ID, API. func ServeHTTP() type HTTPClient var userID No "Get" prefix for getters. func (u *User) Name() string // not GetName() Use gofmt/goimports - no manual formatting debates Tabs for indentation, spaces for alignment No semicolons except in for loops and multi-statement lines Opening brace on same line as declaration Zero values are meaningful: 0, "", nil, false. var buf bytes.Buffer // ready to use, no initialization needed Safe type assertion with ok pattern vs unsafe panic. value, ok := x.(Type) // safe value := x.(Type) // panics if wrong type Type switch for handling multiple types. switch v := x.(type) { case string: // v is string case int: // v is int default: // v is interface{} } Errors are values, not exceptions Handle errors explicitly at each call site Return errors, don't panic Add context when propagating errors Basic error checking pattern with context wrapping. result, err := doSomething() if err != nil { return fmt.Errorf("failed to do something: %w", err) } Use %w verb to wrap errors for later inspection if err != nil { return fmt.Errorf("processing user %s: %w", userID, err) } Do callers need to inspect or unwrap the error? Use %w to wrap errors for errors.Is and errors.As Use %v to format error without wrapping Define package-level error variables var ErrNotFound = errors.New("not found") var ErrInvalidInput = errors.New("invalid input") Define custom error types implementing the error interface for structured error information. type ValidationError struct { Field string Message string }

func (e *ValidationError) Error() string { return fmt.Sprintf("validation failed for %s: %s", e.Field, e.Message) }

Inspect and unwrap errors using errors.Is and errors.As for type-safe error handling. // Check for specific error if errors.Is(err, ErrNotFound) { ... }

// Extract custom error type var valErr *ValidationError if errors.As(err, &valErr) { log.Printf("field: %s", valErr.Field) }

Go 1.20+ errors.Join err := errors.Join(err1, err2, err3)
Accept interfaces, return concrete types Keep interfaces small (1-3 methods) Define interfaces where they are used, not implemented Implicit satisfaction - no "implements" keyword Read(p []byte) (n int, err error) Write(p []byte) (n int, err error) Close() error Error() string String() string Define interfaces with method signatures. type Handler interface { Handle(ctx context.Context, req Request) (Response, error) } Do you have multiple implementations or need to decouple packages? Define interface where it is used for abstraction Use concrete types until abstraction is needed Compose larger interfaces from smaller ones. type ReadWriteCloser interface { io.Reader io.Writer io.Closer } interface{} or any (Go 1.18+) accepts all types. Avoid when possible - loses type safety. func process(data any) { ... } Standard go.mod file structure with module, go version, toolchain, and dependencies. module github.com/user/project

go 1.23

toolchain go1.23.0

require ( github.com/pkg/errors v0.9.1 golang.org/x/sync v0.3.0 )

require ( golang.org/x/sys v0.10.0 // indirect )

Initialize new module Start a new Go project with module support Add missing, remove unused dependencies Clean up go.mod and go.sum files Add or update dependency Package name and optional version Install or update a specific package version Download dependencies to cache Pre-download modules for offline work Create vendor directory Copy dependencies into vendor/ for vendoring Verify dependencies Check that downloaded modules haven't been modified Suggest specific Go toolchain version (Go 1.21+). Used when module requires newer toolchain than default. toolchain go1.23.0 v0.x.x and v1.x.x: no path suffix. import "github.com/user/project" v2+: include version in import path. import "github.com/user/project/v2" Override module location for local development. replace github.com/user/lib => ../lib replace github.com/user/lib v1.0.0 => ./local-lib
Main applications (cmd/myapp/main.go) Private packages, not importable externally Public library code (optional, controversial) API definitions (OpenAPI, protobuf) Configuration files Build/install scripts Test fixtures cmd/myapp/main.go should be minimal - call into internal packages internal/ packages cannot be imported from outside parent module Each directory = one package (except \_test packages) foo.go → foo_test.go Test functions: func TestXxx(t *testing.T) Benchmark functions: func BenchmarkXxx(b *testing.B) Example functions: func ExampleXxx() Table-driven tests for comprehensive test coverage with multiple test cases. func TestAdd(t *testing.T) { tests := []struct { name string a, b int expected int }{ {"positive", 1, 2, 3}, {"negative", -1, -2, -3}, {"zero", 0, 0, 0}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := Add(tt.a, tt.b); got != tt.expected { t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected) } }) } } Do you need to test same logic with multiple inputs and outputs? Use table-driven tests for comprehensive coverage Write simple individual test functions Test helper functions with t.Helper() and t.Cleanup() for better test organization. func setupTestDB(t *testing.T) *DB { t.Helper() db := NewDB() t.Cleanup(func() { db.Close() }) return db } testdata/ directory is ignored by go build and used for test fixtures. mypackage/ ├── main.go ├── main_test.go └── testdata/ ├── input.json └── expected.txt Run tests in current package Execute tests for the current directory Run all tests recursively Test entire project including subpackages Verbose output See detailed test execution output Run specific test Name pattern to match Run only tests matching the pattern Show coverage percentage Get quick coverage summary Generate coverage profile Output file path Create detailed coverage report for analysis Run benchmarks Pattern to match (. for all) Execute performance benchmarks Enable race detector Detect data races during test execution Launch a goroutine for concurrent work. go func() { // concurrent work }() Use sync.WaitGroup to wait for multiple goroutines to complete. var wg sync.WaitGroup for _, item := range items { wg.Add(1) go func(item Item) { defer wg.Done() process(item) }(item) } wg.Wait() Unbuffered channels provide synchronous communication. ch := make(chan int) Buffered channels allow asynchronous communication up to buffer size. ch := make(chan int, 10) Receive-only channel parameter. func consumer(ch <-chan int) Send-only channel parameter. func producer(ch chan<- int) Select statement for multiplexing channel operations. select { case msg := <-ch1: handle(msg) case ch2 <- value: // sent case <-ctx.Done(): return ctx.Err() default: // non-blocking } Closing channels signals no more values will be sent. close(ch) for v := range ch { } // receive until closed Use context.Context for cancellation and timeouts. ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel()

select { case result := <-doWork(ctx): return result, nil case <-ctx.Done(): return nil, ctx.Err() }

Mutual exclusion lock Read-write lock Execute exactly once Wait for goroutine completion Concurrent map (specialized use cases)
Use gofmt/goimports for consistent code formatting Handle errors explicitly at each call site Accept interfaces, return concrete types Keep interfaces small (1-3 methods) Use context.Context for cancellation and timeouts Prefer table-driven tests for comprehensive coverage Use t.Helper() in test helper functions Run tests with -race flag to detect data races Define interfaces where they are used, not implemented Use go mod tidy regularly to maintain clean dependencies Handle all errors explicitly; never ignore returned errors Run go vet and go test before committing Use context.Context for cancellation and timeouts in concurrent code Use gofmt/goimports for consistent formatting Follow Go naming conventions (exported vs unexported) Prefer table-driven tests for comprehensive coverage Run tests with -race flag to detect data races Overusing init() functions makes code harder to test and reason about. Prefer explicit initialization functions that can be called with parameters. Package-level mutable variables create hidden dependencies and concurrency issues. Pass dependencies explicitly through function parameters or struct fields. Defining interfaces prematurely adds unnecessary abstraction. Define interfaces when you have multiple implementations or need to decouple packages. Naked returns in long functions reduce code clarity. Use explicit return statements for functions longer than a few lines. Using panic for recoverable errors violates Go's error handling philosophy. Return errors as values and handle them explicitly at each call site. Goroutines that never exit waste resources and can cause memory leaks. Use context.Context or done channels to ensure goroutines can be cancelled. Data races lead to unpredictable behavior and bugs. Use sync primitives (Mutex, RWMutex) or channels, and always run tests with -race flag. Overusing interface{}/any loses type safety and requires type assertions. Use concrete types or small, focused interfaces when possible. Use Context7 MCP for up-to-date Go documentation Retrieve Go module documentation from Context7. get-library-docs context7CompatibleLibraryID="/golang/website" topic="go.mod modules" Compile package Build executable from current package Specify output name Output binary name Build with custom binary name Compile and install to GOPATH/bin Install package for global use Compile and run Go file to execute Quick compile and execute for development Format all code All packages recursively Standardize code formatting Static analysis All packages recursively Detect suspicious code constructs Run code generators Execute //go:generate directives Cross-compile for different platforms GOOS=linux GOARCH=amd64 go build Build binaries for different operating systems and architectures Understand Go code requirements 1. Check go.mod for module and dependencies 2. Review existing code patterns in project 3. Identify interface and struct designs Write idiomatic Go code 1. Follow Go naming conventions 2. Use interfaces for abstraction 3. Handle errors explicitly Verify Go code correctness 1. Run go build for compilation 2. Run go vet for static analysis 3. Run go test for testing Project architecture, interface design, and package structure planning Go implementation with proper error handling and concurrency patterns Run go vet, go fmt, and ensure idiomatic Go code Navigate Go packages and symbol definitions efficiently Access latest Go standard library and toolchain documentation Debug goroutine leaks, race conditions, and performance issues Golint style warning Fix style issue, maintain idiomatic code Compilation error Fix error, verify with go build Breaking change in exported API Stop, present migration options to user Data race or unsafe memory operation Block operation, require safe implementation Handle all errors explicitly Follow Go naming conventions (exported vs unexported) Use interfaces for testability Ignoring returned errors Using init() without strong justification Overusing global variables