Agent skill
go-project-layout
Use when starting a new Go project, organizing packages, or restructuring an existing Go codebase. Covers standard directory layout, package design, Makefile targets, Dockerfile patterns, and module setup.
Install this agent skill to your Project
npx add-skill https://github.com/saisudhir14/claude-skills/tree/main/skills/go-project-layout
Metadata
Additional technical details for this skill
- tags
- golang go project-layout structure makefile dockerfile module
- author
- saisudhir14
- category
- languages
SKILL.md
Go Project Layout
Standard project structure and setup patterns for Go.
Directory Structure
Small projects (libraries, CLIs) should stay flat. Only add structure when the project warrants it. Do not create directories speculatively.
Application Layout
myapp/
├── cmd/
│ └── myapp/
│ └── main.go # entry point, minimal logic
├── internal/
│ ├── server/
│ │ └── server.go # HTTP server setup
│ ├── handler/
│ │ └── user.go # HTTP handlers
│ ├── service/
│ │ └── user.go # business logic
│ └── store/
│ └── postgres.go # data access
├── go.mod
├── go.sum
├── Makefile
├── Dockerfile
├── .golangci.yml
└── README.md
Library Layout
mylib/
├── mylib.go # primary package API
├── mylib_test.go
├── internal/
│ └── parse/ # unexported helpers
│ └── parse.go
├── go.mod
└── README.md
Key Directories
cmd/
Each subdirectory is an executable. Keep main.go minimal: parse flags, build dependencies, call run().
// cmd/myapp/main.go
package main
import (
"context"
"fmt"
"os"
"myapp/internal/server"
)
func main() {
if err := run(context.Background()); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run(ctx context.Context) error {
srv, err := server.New()
if err != nil {
return fmt.Errorf("create server: %w", err)
}
return srv.Start(ctx)
}
internal/
Packages under internal/ cannot be imported by other modules. Use this for code that is not part of your public API. The Go toolchain enforces this.
When NOT to use certain directories
pkg/: Avoid. If code is meant to be imported, put it at the module root or in a named package.pkg/adds a directory with no meaning.src/: Not a Go convention. Do not use.models//types//utils/: These become dumping grounds. Name packages by what they do, not what they contain.
Module Setup
mkdir myapp && cd myapp
go mod init github.com/yourorg/myapp
go.mod with Tool Dependencies (Go 1.24+)
module github.com/yourorg/myapp
go 1.25
tool (
github.com/golangci/golangci-lint/cmd/golangci-lint
golang.org/x/tools/cmd/stringer
)
Makefile
.PHONY: build test lint run clean
build: ## Build the binary
go build -o bin/myapp ./cmd/myapp
test: ## Run tests
go test -race -count=1 ./...
lint: ## Run linters
go tool golangci-lint run ./...
run: build ## Build and run
./bin/myapp
clean: ## Remove build artifacts
rm -rf bin/
Dockerfile
Multi-stage build for small, secure images:
FROM golang:1.25 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /bin/myapp ./cmd/myapp
FROM gcr.io/distroless/static-debian12
COPY --from=build /bin/myapp /bin/myapp
ENTRYPOINT ["/bin/myapp"]
Key points:
CGO_ENABLED=0for static binary (no libc dependency)- Distroless base image: no shell, no package manager, smaller attack surface
- Copy
go.modandgo.sumfirst for Docker layer caching
Package Design Rules
- Name by purpose, not contents:
storenotmodels,authnotutils - One package, one idea: a package should do one thing well
- Avoid circular imports: if A imports B and B needs A, extract the shared type into a third package
- internal for private code: anything under
internal/is hidden from external importers - Keep cmd/ thin: main.go builds dependencies and calls into internal packages
- Accept interfaces, return structs: define interfaces where they are used, return concrete types
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
go-code-review
Use when reviewing Go code or preparing code for review. Quick-reference checklist covering naming, error handling, concurrency, testing, imports, documentation, and common pitfalls. Based on Go Wiki CodeReviewComments.
go-concurrency
Use when writing, reviewing, or debugging concurrent Go code. Covers goroutine lifecycle management, channels, errgroup, mutexes, atomics, sync.Map, and synchronous-first design. Based on Google and Uber style guides.
go-security
Use when writing, reviewing, or auditing Go code for security. Covers input validation, SQL injection prevention, path traversal, secrets management, cryptography, HTTP security headers, and dependency scanning.
go-error-handling
Use when writing, reviewing, or debugging Go error handling code. Covers error wrapping, sentinel errors, custom error types, error joining, single handling, and error flow patterns. Based on Google and Uber style guides.
go-performance
Use when writing, reviewing, or optimizing Go code for performance. Covers string operations, memory allocation, preallocating slices and maps, strings.Builder, strconv, container-aware GOMAXPROCS, and runtime considerations for Go 1.25.
go-testing
Use when writing, reviewing, or debugging Go tests and benchmarks. Covers table-driven tests, parallel execution, go-cmp, T.Context, T.Chdir, b.Loop, synctest for deterministic concurrency testing, and test failure messages.
Didn't find tool you were looking for?