.agent/skills/go-patterns/SKILL.md
Go/Golang best practices, patterns, and idioms for building performant, concurrent applications.
npx skillsauth add Rikinshah787/clawarmy go-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Simple, efficient, concurrent. The Go way.
"Don't communicate by sharing memory; share memory by communicating."
project/
├── cmd/
│ └── myapp/
│ └── main.go # Entry point
├── internal/
│ ├── handler/ # HTTP handlers
│ ├── service/ # Business logic
│ └── repository/ # Data access
├── pkg/
│ └── utils/ # Reusable packages
├── api/
│ └── openapi.yaml # API specs
├── go.mod
└── go.sum
// Always handle errors explicitly
result, err := doSomething()
if err != nil {
return fmt.Errorf("failed to do something: %w", err)
}
// Wrap errors with context
if err := db.Create(&user); err != nil {
return fmt.Errorf("creating user %s: %w", user.Email, err)
}
// BAD: Ignoring errors
result, _ := doSomething()
// BAD: No context
if err != nil {
return err
}
func processItems(items []Item) {
var wg sync.WaitGroup
for _, item := range items {
wg.Add(1)
go func(i Item) {
defer wg.Done()
process(i)
}(item)
}
wg.Wait()
}
// Worker pool
func workerPool(jobs <-chan Job, results chan<- Result, workers int) {
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
wg.Wait()
close(results)
}
func fetchWithTimeout(ctx context.Context, url string) ([]byte, error) {
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
// ✅ GOOD: Small, focused interfaces
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
// Compose when needed
type ReadWriter interface {
Reader
Writer
}
// ✅ GOOD: Accept interface
func ProcessData(r io.Reader) error {
// Can accept any Reader
}
// ✅ GOOD: Return concrete type
func NewService() *Service {
return &Service{}
}
type Handler struct {
service *Service
logger *slog.Logger
}
func NewHandler(svc *Service, log *slog.Logger) *Handler {
return &Handler{service: svc, logger: log}
}
func (h *Handler) GetUser(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
user, err := h.service.GetUser(r.Context(), id)
if err != nil {
if errors.Is(err, ErrNotFound) {
http.Error(w, "user not found", http.StatusNotFound)
return
}
h.logger.Error("failed to get user", "error", err)
http.Error(w, "internal error", http.StatusInternalServerError)
return
}
json.NewEncoder(w).Encode(user)
}
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive", 2, 3, 5},
{"negative", -1, -1, -2},
{"zero", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d",
tt.a, tt.b, result, tt.expected)
}
})
}
}
type UserRepository interface {
Get(ctx context.Context, id string) (*User, error)
}
// Mock for testing
type mockUserRepo struct {
user *User
err error
}
func (m *mockUserRepo) Get(ctx context.Context, id string) (*User, error) {
return m.user, m.err
}
// ✅ GOOD: Reuse buffers
var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
func process() {
buf := bufPool.Get().(*bytes.Buffer)
defer func() {
buf.Reset()
bufPool.Put(buf)
}()
// Use buffer
}
// ✅ GOOD: Pre-allocate when size known
users := make([]User, 0, len(ids))
for _, id := range ids {
users = append(users, getUser(id))
}
// ❌ BAD: Multiple reallocations
var users []User
for _, id := range ids {
users = append(users, getUser(id))
}
| ❌ Don't | ✅ Do |
|----------|-------|
| panic for errors | Return errors |
| Global mutable state | Dependency injection |
| init() side effects | Explicit initialization |
| Naked goroutines | Manage lifecycle |
| Empty interface any | Typed interfaces |
# Format code
gofmt -w .
# Lint
golangci-lint run
# Vet
go vet ./...
# Test with coverage
go test -cover ./...
Remember: "Clear is better than clever." - Go Proverbs
content-media
Elite UX engineer scouting friction points and optimizing user-centered design. User flows, conversion optimization, and design system enforcement.
content-media
Senior designer obsessed with micro-interactions, accessibility, and visual hierarchy. Create interfaces that are beautiful, usable, and inclusive.
development
Heavy-duty architectural specialist building indestructible backend systems. API design, microservices, DDD, and database-backed services.
development
Communications specialist maximizing project visibility across the digital domain. SEO, meta optimization, structured data, and web analytics.