standards-golang

Core Rule: Use Go modules for dependencies, go test for testing, gofmt + go vet + golangci-lint for quality. Write idiomatic Go with explicit error handling.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "standards-golang" with this command: npx skills add maxritter/claude-codepro/maxritter-claude-codepro-standards-golang

Go Standards

Core Rule: Use Go modules for dependencies, go test for testing, gofmt + go vet + golangci-lint for quality. Write idiomatic Go with explicit error handling.

When to use this skill

  • When creating or managing Go modules and dependencies

  • When writing or running tests in Go projects

  • When formatting Go code or fixing linting issues

  • When implementing error handling patterns

  • When organizing package structure

  • When deciding whether to create a new Go file or extend existing ones

  • When setting up code quality checks (formatting, vetting, linting)

  • When ensuring code follows Go idioms and best practices

Module Management

Use Go modules for all dependency management:

Initialize a new module

go mod init github.com/org/project

Dependencies are added automatically via imports

Then run tidy to update go.mod and go.sum

go mod tidy

Update all dependencies

go get -u ./...

Update specific dependency

go get -u github.com/pkg/name@latest

Verify dependencies

go mod verify

Clean module cache

go clean -modcache

Module file structure:

  • go.mod

  • Module definition and direct dependencies

  • go.sum

  • Cryptographic checksums for dependencies

Testing with go test

Run tests using standard go test:

go test ./... # All tests go test ./pkg/... # Tests in pkg/ and subdirs go test -v ./... # Verbose output (debugging only) go test -short ./... # Skip long-running tests go test -race ./... # With race detector go test -cover ./... # With coverage summary go test -coverprofile=coverage.out ./... # Generate coverage file go tool cover -html=coverage.out # View coverage in browser

Test file naming: Tests go in *_test.go files alongside the code they test.

Test function naming: func TestFunctionName(t *testing.T)

func TestProcessOrder(t *testing.T) { order := Order{ID: "123", Amount: 100} result, err := ProcessOrder(order)

if err != nil {
    t.Fatalf("unexpected error: %v", err)
}
if result.Status != "completed" {
    t.Errorf("got status %q, want %q", result.Status, "completed")
}

}

Table-driven tests: Preferred for testing multiple cases:

func TestValidateEmail(t *testing.T) { tests := []struct { name string email string wantErr bool }{ {"valid email", "user@example.com", false}, {"missing @", "userexample.com", true}, {"empty", "", true}, }

for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        err := ValidateEmail(tt.email)
        if (err != nil) != tt.wantErr {
            t.Errorf("ValidateEmail(%q) error = %v, wantErr %v", tt.email, err, tt.wantErr)
        }
    })
}

}

Code Quality Tools

Formatting with gofmt:

gofmt -w . # Format all Go files in place gofmt -d . # Show diff without modifying goimports -w . # Format + organize imports

Static analysis with go vet:

go vet ./... # Check for common mistakes

Comprehensive linting with golangci-lint:

golangci-lint run # Run all enabled linters golangci-lint run --fix # Auto-fix where possible golangci-lint run --fast # Quick check (fewer linters)

Run quality checks before marking work complete.

Error Handling

Always handle errors explicitly. Never ignore them.

// REQUIRED - handle the error result, err := doSomething() if err != nil { return fmt.Errorf("doing something: %w", err) }

// FORBIDDEN - ignoring errors result, _ := doSomething() // Never do this

Error wrapping: Add context when propagating errors:

func ProcessUser(userID string) error { user, err := fetchUser(userID) if err != nil { return fmt.Errorf("fetching user %s: %w", userID, err) }

if err := validateUser(user); err != nil {
    return fmt.Errorf("validating user %s: %w", userID, err)
}

return nil

}

Custom errors: Use for domain-specific error types:

var ErrNotFound = errors.New("not found") var ErrInvalidInput = errors.New("invalid input")

// Check with errors.Is if errors.Is(err, ErrNotFound) { // handle not found }

Code Style

Naming conventions:

Type Convention Example

Packages lowercase, single word http , json , user

Exported PascalCase ProcessOrder , UserService

Unexported camelCase processOrder , userService

Acronyms ALL CAPS HTTPServer , XMLParser , ID

Interfaces -er suffix (often) Reader , Writer , Handler

Comments for exported functions:

// ProcessOrder validates and processes the given order. // It returns ErrInvalidOrder if the order is malformed. func ProcessOrder(order Order) error { // implementation }

Import organization: Standard library, then third-party, then local:

import ( "context" "fmt" "net/http"

"github.com/gin-gonic/gin"
"go.uber.org/zap"

"github.com/myorg/myproject/internal/service"

)

Common Patterns

Context propagation: Always pass context as first parameter:

func ProcessRequest(ctx context.Context, req Request) (Response, error) { // Use ctx for cancellation, timeouts, and request-scoped values result, err := db.QueryContext(ctx, query) if err != nil { return Response{}, err } return Response{Data: result}, nil }

Defer for cleanup:

func ReadFile(path string) ([]byte, error) { f, err := os.Open(path) if err != nil { return nil, err } defer f.Close() // Guaranteed to run on function exit

return io.ReadAll(f)

}

Struct initialization:

// Named fields (preferred for clarity) user := User{ ID: "123", Name: "Alice", Email: "alice@example.com", }

// Zero values are valid - use them var count int // 0 var name string // "" var items []string // nil (valid for append)

File Organization

Prefer editing existing files over creating new ones.

Before creating a new Go file, ask:

  • Can this fit in an existing package?

  • Is there a related file to extend?

  • Does this truly need to be separate?

Standard project structure:

project/ ├── cmd/ # Main applications │ └── server/ │ └── main.go ├── internal/ # Private packages (can't be imported externally) │ ├── handler/ │ ├── service/ │ └── repository/ ├── pkg/ # Public packages (can be imported) │ └── api/ ├── go.mod └── go.sum

Verification Checklist

Before marking Go work complete:

  • Code formatted: gofmt -w .

  • Tests pass: go test ./...

  • Static analysis clean: go vet ./...

  • Linting clean: golangci-lint run

  • All errors handled (no _ for errors)

  • Dependencies tidy: go mod tidy

  • Context propagated where needed

  • Exported functions have comments

Quick Reference

Task Command

Init module go mod init module-name

Add dependency go get github.com/pkg/name

Run tests go test ./...

Run with coverage go test -cover ./...

Format code gofmt -w .

Static analysis go vet ./...

Lint golangci-lint run

Tidy dependencies go mod tidy

Build go build ./...

Run go run ./cmd/app

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

update-refs

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

go standards

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

testing standards

No summary provided by upstream source.

Repository SourceNeeds Review