1---2name: go-ecosystem3description: 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. Use when this capability is needed.4---56<purpose>7Provide comprehensive patterns for Go language development, modules, testing, and idiomatic coding practices.8</purpose>910<go_language>11<naming_conventions>12<pattern name="packages">13<description>Lowercase, single-word names. No underscores or mixedCaps.</description>14<example>15package httputil16</example>17</pattern>1819<pattern name="exported">20<description>PascalCase for exported (public) identifiers.</description>21<example>22func ReadFile()23type Handler24var MaxRetries25</example>26</pattern>2728<pattern name="unexported">29<description>camelCase for unexported (private) identifiers.</description>30<example>31func parseConfig()32type handler33var maxRetries34</example>35</pattern>3637<pattern name="interfaces">38<description>Single-method interfaces: method name + "er" suffix.</description>39<example>40Reader, Writer, Closer, Stringer, Handler41</example>42</pattern>4344<pattern name="acronyms">45<description>Keep acronyms uppercase: URL, HTTP, ID, API.</description>46<example>47func ServeHTTP()48type HTTPClient49var userID50</example>51</pattern>5253<pattern name="getters">54<description>No "Get" prefix for getters.</description>55<example>56func (u *User) Name() string // not GetName()57</example>58</pattern>59</naming_conventions>6061<formatting>62<rules priority="standard">63<rule>Use gofmt/goimports - no manual formatting debates</rule>64<rule>Tabs for indentation, spaces for alignment</rule>65<rule>No semicolons except in for loops and multi-statement lines</rule>66<rule>Opening brace on same line as declaration</rule>67</rules>68</formatting>6970<type_system>71<pattern name="zero_values">72<description>Zero values are meaningful: 0, "", nil, false.</description>73<example>74var buf bytes.Buffer // ready to use, no initialization needed75</example>76</pattern>7778<pattern name="type_assertion">79<description>Safe type assertion with ok pattern vs unsafe panic.</description>80<example>81value, ok := x.(Type) // safe82value := x.(Type) // panics if wrong type83</example>84</pattern>8586<pattern name="type_switch">87<description>Type switch for handling multiple types.</description>88<example>89switch v := x.(type) {90case string: // v is string91case int: // v is int92default: // v is interface{}93}94</example>95</pattern>96</type_system>97</go_language>9899<error_handling>100<principles>101<principle>Errors are values, not exceptions</principle>102<principle>Handle errors explicitly at each call site</principle>103<principle>Return errors, don't panic</principle>104<principle>Add context when propagating errors</principle>105</principles>106107<pattern name="basic_check">108<description>Basic error checking pattern with context wrapping.</description>109<example>110result, err := doSomething()111if err != nil {112 return fmt.Errorf("failed to do something: %w", err)113}114</example>115</pattern>116117<pattern name="wrap_with_context">118<description>Use %w verb to wrap errors for later inspection</description>119<example>120if err != nil {121 return fmt.Errorf("processing user %s: %w", userID, err)122}123</example>124</pattern>125126<pattern name="sentinel_errors">127<description>Define package-level error variables</description>128<example>129var ErrNotFound = errors.New("not found")130var ErrInvalidInput = errors.New("invalid input")131</example>132</pattern>133134<pattern name="custom_error_type">135<description>Define custom error types implementing the error interface for structured error information.</description>136<example>137type ValidationError struct {138 Field string139 Message string140}141142func (e \*ValidationError) Error() string {143return fmt.Sprintf("validation failed for %s: %s", e.Field, e.Message)144}145</example>146</pattern>147148<pattern name="error_inspection">149<description>Inspect and unwrap errors using errors.Is and errors.As for type-safe error handling.</description>150<example>151// Check for specific error152if errors.Is(err, ErrNotFound) { ... }153154// Extract custom error type155var valErr \*ValidationError156if errors.As(err, &valErr) {157log.Printf("field: %s", valErr.Field)158}159</example>160</pattern>161162<pattern name="multiple_errors">163<description>Go 1.20+ errors.Join</description>164<example>165err := errors.Join(err1, err2, err3)166</example>167</pattern>168</error_handling>169170<interfaces>171<principles>172<principle>Accept interfaces, return concrete types</principle>173<principle>Keep interfaces small (1-3 methods)</principle>174<principle>Define interfaces where they are used, not implemented</principle>175<principle>Implicit satisfaction - no "implements" keyword</principle>176</principles>177178<common_interfaces>179<interface name="io.Reader">Read(p []byte) (n int, err error)</interface>180<interface name="io.Writer">Write(p []byte) (n int, err error)</interface>181<interface name="io.Closer">Close() error</interface>182<interface name="error">Error() string</interface>183<interface name="fmt.Stringer">String() string</interface>184</common_interfaces>185186<pattern name="interface_definition">187<description>Define interfaces with method signatures.</description>188<example>189type Handler interface {190 Handle(ctx context.Context, req Request) (Response, error)191}192</example>193</pattern>194195<pattern name="interface_composition">196<description>Compose larger interfaces from smaller ones.</description>197<example>198type ReadWriteCloser interface {199 io.Reader200 io.Writer201 io.Closer202}203</example>204</pattern>205206<pattern name="empty_interface">207<description>interface{} or any (Go 1.18+) accepts all types. Avoid when possible - loses type safety.</description>208<example>209func process(data any) { ... }210</example>211</pattern>212</interfaces>213214<modules>215<pattern name="go_mod_structure">216<description>Standard go.mod file structure with module, go version, toolchain, and dependencies.</description>217<example>218module github.com/user/project219220go 1.23221222toolchain go1.23.0223224require (225github.com/pkg/errors v0.9.1226golang.org/x/sync v0.3.0227)228229require (230golang.org/x/sys v0.10.0 // indirect231)232</example>233</pattern>234235<commands>236<tool name="go mod init">237<description>Initialize new module</description>238<use_case>Start a new Go project with module support</use_case>239</tool>240<tool name="go mod tidy">241<description>Add missing, remove unused dependencies</description>242<use_case>Clean up go.mod and go.sum files</use_case>243</tool>244<tool name="go get">245<description>Add or update dependency</description>246<param name="package-name@version">Package name and optional version</param>247<use_case>Install or update a specific package version</use_case>248</tool>249<tool name="go mod download">250<description>Download dependencies to cache</description>251<use_case>Pre-download modules for offline work</use_case>252</tool>253<tool name="go mod vendor">254<description>Create vendor directory</description>255<use_case>Copy dependencies into vendor/ for vendoring</use_case>256</tool>257<tool name="go mod verify">258<description>Verify dependencies</description>259<use_case>Check that downloaded modules haven't been modified</use_case>260</tool>261</commands>262263<pattern name="toolchain_directive">264<description>Suggest specific Go toolchain version (Go 1.21+). Used when module requires newer toolchain than default.</description>265<example>266toolchain go1.23.0267</example>268</pattern>269270<versioning>271<pattern name="semantic_import">272<description>v0.x.x and v1.x.x: no path suffix.</description>273<example>274import "github.com/user/project"275</example>276</pattern>277<pattern name="v2_plus">278<description>v2+: include version in import path.</description>279<example>280import "github.com/user/project/v2"281</example>282</pattern>283</versioning>284285<pattern name="replace_directive">286<description>Override module location for local development.</description>287<example>288replace github.com/user/lib => ../lib289replace github.com/user/lib v1.0.0 => ./local-lib290</example>291</pattern>292</modules>293294<project_structure>295<standard_layout>296<directory name="cmd/">Main applications (cmd/myapp/main.go)</directory>297<directory name="internal/">Private packages, not importable externally</directory>298<directory name="pkg/">Public library code (optional, controversial)</directory>299<directory name="api/">API definitions (OpenAPI, protobuf)</directory>300<directory name="configs/">Configuration files</directory>301<directory name="scripts/">Build/install scripts</directory>302<directory name="testdata/">Test fixtures</directory>303</standard_layout>304305<best_practices>306<practice priority="critical">cmd/myapp/main.go should be minimal - call into internal packages</practice>307<practice priority="critical">internal/ packages cannot be imported from outside parent module</practice>308<practice priority="high">Each directory = one package (except \_test packages)</practice>309</best_practices>310</project_structure>311312<testing>313<file_naming>314<pattern name="test_files">315<description>foo.go → foo_test.go</description>316</pattern>317<pattern name="test_functions">318<description>Test functions: func TestXxx(t *testing.T)</description>319</pattern>320<pattern name="benchmark_functions">321<description>Benchmark functions: func BenchmarkXxx(b *testing.B)</description>322</pattern>323<pattern name="example_functions">324<description>Example functions: func ExampleXxx()</description>325</pattern>326</file_naming>327328<pattern name="table_driven_tests">329<description>Table-driven tests for comprehensive test coverage with multiple test cases.</description>330<example>331func TestAdd(t *testing.T) {332 tests := []struct {333 name string334 a, b int335 expected int336 }{337 {"positive", 1, 2, 3},338 {"negative", -1, -2, -3},339 {"zero", 0, 0, 0},340 }341 for _, tt := range tests {342 t.Run(tt.name, func(t *testing.T) {343 if got := Add(tt.a, tt.b); got != tt.expected {344 t.Errorf("Add(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.expected)345 }346 })347 }348}349</example>350</pattern>351352<pattern name="test_helpers">353<description>Test helper functions with t.Helper() and t.Cleanup() for better test organization.</description>354<example>355func setupTestDB(t *testing.T) *DB {356 t.Helper()357 db := NewDB()358 t.Cleanup(func() { db.Close() })359 return db360}361</example>362</pattern>363364<pattern name="testdata_directory">365<description>testdata/ directory is ignored by go build and used for test fixtures.</description>366<example>367mypackage/368├── main.go369├── main_test.go370└── testdata/371 ├── input.json372 └── expected.txt373</example>374</pattern>375376<commands>377<tool name="go test">378<description>Run tests in current package</description>379<use_case>Execute tests for the current directory</use_case>380</tool>381<tool name="go test ./...">382<description>Run all tests recursively</description>383<use_case>Test entire project including subpackages</use_case>384</tool>385<tool name="go test -v">386<description>Verbose output</description>387<use_case>See detailed test execution output</use_case>388</tool>389<tool name="go test -run">390<description>Run specific test</description>391<param name="TestName">Name pattern to match</param>392<use_case>Run only tests matching the pattern</use_case>393</tool>394<tool name="go test -cover">395<description>Show coverage percentage</description>396<use_case>Get quick coverage summary</use_case>397</tool>398<tool name="go test -coverprofile">399<description>Generate coverage profile</description>400<param name="c.out">Output file path</param>401<use_case>Create detailed coverage report for analysis</use_case>402</tool>403<tool name="go test -bench">404<description>Run benchmarks</description>405<param name=".">Pattern to match (. for all)</param>406<use_case>Execute performance benchmarks</use_case>407</tool>408<tool name="go test -race">409<description>Enable race detector</description>410<use_case>Detect data races during test execution</use_case>411</tool>412</commands>413</testing>414415<concurrency>416<goroutines>417<pattern name="launch">418<description>Launch a goroutine for concurrent work.</description>419<example>420go func() {421 // concurrent work422}()423</example>424</pattern>425426<pattern name="with_waitgroup">427<description>Use sync.WaitGroup to wait for multiple goroutines to complete.</description>428<example>429var wg sync.WaitGroup430for _, item := range items {431 wg.Add(1)432 go func(item Item) {433 defer wg.Done()434 process(item)435 }(item)436}437wg.Wait()438</example>439</pattern>440</goroutines>441442<channels>443<pattern name="unbuffered">444<description>Unbuffered channels provide synchronous communication.</description>445<example>446ch := make(chan int)447</example>448</pattern>449450<pattern name="buffered">451<description>Buffered channels allow asynchronous communication up to buffer size.</description>452<example>453ch := make(chan int, 10)454</example>455</pattern>456457<pattern name="receive_only">458<description>Receive-only channel parameter.</description>459<example>460func consumer(ch <-chan int)461</example>462</pattern>463464<pattern name="send_only">465<description>Send-only channel parameter.</description>466<example>467func producer(ch chan<- int)468</example>469</pattern>470471<pattern name="select">472<description>Select statement for multiplexing channel operations.</description>473<example>474select {475case msg := <-ch1:476 handle(msg)477case ch2 <- value:478 // sent479case <-ctx.Done():480 return ctx.Err()481default:482 // non-blocking483}484</example>485</pattern>486487<pattern name="close_channel">488<description>Closing channels signals no more values will be sent.</description>489<example>490close(ch)491for v := range ch { } // receive until closed492</example>493</pattern>494</channels>495496<pattern name="context_usage">497<description>Use context.Context for cancellation and timeouts.</description>498<example>499ctx, cancel := context.WithTimeout(ctx, 5*time.Second)500defer cancel()501502select {503case result := <-doWork(ctx):504return result, nil505case <-ctx.Done():506return nil, ctx.Err()507}508</example>509</pattern>510511<sync_package>512<concept name="sync.Mutex">513<description>Mutual exclusion lock</description>514</concept>515<concept name="sync.RWMutex">516<description>Read-write lock</description>517</concept>518<concept name="sync.Once">519<description>Execute exactly once</description>520</concept>521<concept name="sync.WaitGroup">522<description>Wait for goroutine completion</description>523</concept>524<concept name="sync.Map">525<description>Concurrent map (specialized use cases)</description>526</concept>527</sync_package>528</concurrency>529530<best_practices>531<practice priority="high">Use gofmt/goimports for consistent code formatting</practice>532<practice priority="high">Handle errors explicitly at each call site</practice>533<practice priority="high">Accept interfaces, return concrete types</practice>534<practice priority="high">Keep interfaces small (1-3 methods)</practice>535<practice priority="high">Use context.Context for cancellation and timeouts</practice>536<practice priority="medium">Prefer table-driven tests for comprehensive coverage</practice>537<practice priority="medium">Use t.Helper() in test helper functions</practice>538<practice priority="medium">Run tests with -race flag to detect data races</practice>539<practice priority="medium">Define interfaces where they are used, not implemented</practice>540<practice priority="medium">Use go mod tidy regularly to maintain clean dependencies</practice>541</best_practices>542543<anti_patterns>544<avoid name="init_overuse">545<description>Overusing init() functions makes code harder to test and reason about.</description>546<instead>Prefer explicit initialization functions that can be called with parameters.</instead>547</avoid>548<avoid name="global_state">549<description>Package-level mutable variables create hidden dependencies and concurrency issues.</description>550<instead>Pass dependencies explicitly through function parameters or struct fields.</instead>551</avoid>552<avoid name="interface_pollution">553<description>Defining interfaces prematurely adds unnecessary abstraction.</description>554<instead>Define interfaces when you have multiple implementations or need to decouple packages.</instead>555</avoid>556<avoid name="naked_returns">557<description>Naked returns in long functions reduce code clarity.</description>558<instead>Use explicit return statements for functions longer than a few lines.</instead>559</avoid>560<avoid name="panic_for_errors">561<description>Using panic for recoverable errors violates Go's error handling philosophy.</description>562<instead>Return errors as values and handle them explicitly at each call site.</instead>563</avoid>564<avoid name="goroutine_leak">565<description>Goroutines that never exit waste resources and can cause memory leaks.</description>566<instead>Use context.Context or done channels to ensure goroutines can be cancelled.</instead>567</avoid>568<avoid name="data_race">569<description>Data races lead to unpredictable behavior and bugs.</description>570<instead>Use sync primitives (Mutex, RWMutex) or channels, and always run tests with -race flag.</instead>571</avoid>572<avoid name="empty_interface_overuse">573<description>Overusing interface{}/any loses type safety and requires type assertions.</description>574<instead>Use concrete types or small, focused interfaces when possible.</instead>575</avoid>576</anti_patterns>577578<context7_integration>579<description>Use Context7 MCP for up-to-date Go documentation</description>580581<go_libraries>582<library name="Go Website" id="/golang/website" trust="8.3" />583<library name="Go Tools" id="/golang/tools" trust="8.3" />584</go_libraries>585586<usage_patterns>587<pattern name="module_reference">588<description>Retrieve Go module documentation from Context7.</description>589<example>590get-library-docs context7CompatibleLibraryID="/golang/website" topic="go.mod modules"591</example>592</pattern>593</usage_patterns>594</context7_integration>595596<build_commands>597<tool name="go build">598<description>Compile package</description>599<use_case>Build executable from current package</use_case>600</tool>601<tool name="go build -o">602<description>Specify output name</description>603604<param name="name">Output binary name</param>605<use_case>Build with custom binary name</use_case>606</tool>607<tool name="go install">608<description>Compile and install to GOPATH/bin</description>609<use_case>Install package for global use</use_case>610</tool>611<tool name="go run">612<description>Compile and run</description>613<param name="main.go">Go file to execute</param>614<use_case>Quick compile and execute for development</use_case>615</tool>616<tool name="go fmt">617<description>Format all code</description>618<param name="./...">All packages recursively</param>619<use_case>Standardize code formatting</use_case>620</tool>621<tool name="go vet">622<description>Static analysis</description>623<param name="./...">All packages recursively</param>624<use_case>Detect suspicious code constructs</use_case>625</tool>626<tool name="go generate">627<description>Run code generators</description>628<use_case>Execute //go:generate directives</use_case>629</tool>630<tool name="cross-compile">631<description>Cross-compile for different platforms</description>632<example>633GOOS=linux GOARCH=amd64 go build634</example>635<use_case>Build binaries for different operating systems and architectures</use_case>636</tool>637</build_commands>638639---640> Converted and distributed by [TomeVault](https://tomevault.io/claim/mtaku3) — claim your Tome and manage your conversions.641<!-- tomevault:4.0:skill_md:2026-04-13 -->