golang
Scannednpx machina-cli add skill DigitalPine/claude-skills/golang --openclawGo Project Setup & Audit
Philosophy
Fast by default, comprehensive when needed.
Most Go projects start as a single main.go. That's fine. Add structure when you feel pain, not before. This skill offers two tiers:
| Tier | When | Time | Linters |
|---|---|---|---|
| Quick Start | New idea, CLI tool, prototype | 2 min | 5 essential |
| Full Setup | Growing codebase, team project | 10 min | 40+ comprehensive |
Start with Quick Start. Graduate to Full Setup when:
- Multiple people contributing
- Codebase exceeds ~5k lines
- You're shipping to production users
When to Use
- "Create a new Go project"
- "Set up a Go CLI/API/library"
- "Audit this Go project"
- "Add linting to my Go project"
Quick Start (Recommended for New Projects)
5 steps, 2 minutes, ready to code:
1. Initialize
mkdir myproject && cd myproject
go mod init github.com/yourorg/myproject
2. Add Essential Tooling
go get -tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest
go install github.com/air-verse/air@latest # Hot reload
3. Copy Minimal Configs
Copy from assets/ to project root:
.golangci.minimal.yml→.golangci.ymlMakefile.minimal→Makefile.gitignoreair.toml(optional, for hot reload)
Update local-prefixes in .golangci.yml to your module path.
4. Create Entry Point
// main.go
package main
import (
"log/slog"
"os"
)
func main() {
if err := run(); err != nil {
slog.Error("fatal", "error", err)
os.Exit(1)
}
}
func run() error {
slog.Info("starting")
// Your code here
return nil
}
5. Verify
make lint # Should pass
make test # Should pass (no tests yet is fine)
make dev # Hot reload running
Done. Start coding.
Full Setup (Growing Projects)
When Quick Start isn't enough, upgrade:
Structure Upgrade
mkdir -p cmd/myproject internal/{handler,service,config}
mv main.go cmd/myproject/
See references/structure.md for when each directory makes sense.
Linter Upgrade
Replace .golangci.yml with assets/.golangci.yml (full config).
Build Upgrade
Replace Makefile with assets/Makefile (or Taskfile.yml).
Audit Mode
For existing projects, check these in order:
Critical (Fix Now)
| Check | Command | Fix |
|---|---|---|
| No linting | ls .golangci.yml | Add config from assets/ |
| Errors ignored | grep -r "err :=" | grep -v "if err" | Handle or explicitly ignore |
| No tests | find . -name "*_test.go" | Add tests for critical paths |
Important (Fix Soon)
| Check | Issue | Fix |
|---|---|---|
| go.mod version | < go 1.22 | Update, get loop variable fix |
| tools.go exists | Pre-1.24 pattern | Migrate to tool directive |
| Bare error returns | return err with no context | Wrap: fmt.Errorf("op: %w", err) |
Using log package | No structure | Switch to slog |
Nice to Have
| Check | Fix |
|---|---|
| No Makefile | Add from assets/ |
| No .gitignore | Add from assets/ |
| Flat structure at >3k LOC | Consider cmd/internal/ |
Quick Reference
| Need | Reference |
|---|---|
| "Should I add internal/?" | references/structure.md |
| "What linters matter?" | references/linting.md |
| "How to wrap errors?" | references/errors.md |
| "Testing patterns?" | references/testing.md |
| "What's new in Go 1.25?" | references/go-1.25.md |
Decision Shortcuts
Web framework?
- stdlib
net/http+chirouter (simple, idiomatic) - Skip frameworks until you outgrow chi
Database?
sqlc(type-safe, generates code from SQL)sqlxif you want more flexibility
Config?
os.Getenv()+.envfile for devenvconfigif you need struct binding
Logging?
slog(stdlib, structured, fast enough)
Assets Summary
| File | Purpose | When |
|---|---|---|
.golangci.minimal.yml | 5 essential linters | Quick Start |
.golangci.yml | 40+ linters | Full Setup |
Makefile.minimal | run/test/lint/dev | Quick Start |
Makefile | All targets | Full Setup |
Taskfile.yml | YAML alternative | Preference |
.gitignore | Standard ignores | Always |
air.toml | Hot reload config | Development |
Anti-Patterns (Don't Do These)
| Mistake | Why | Do Instead |
|---|---|---|
| Create cmd/internal/pkg day 1 | Over-engineering | Start flat |
| Enable all linters immediately | Friction kills velocity | Start with 5 |
| Custom error types early | YAGNI | Use fmt.Errorf |
| Global logger | Hard to test | Inject via struct/context |
tools.go file | Outdated (pre-Go 1.24) | Use tool directive |
The Only Rules
- Don't ignore errors - Handle or explicitly
_ = fn() - Wrap with context -
fmt.Errorf("operation: %w", err) - Run the linter -
make lintbefore commit - Write some tests - At least for the tricky parts
Everything else is optional until it isn't.
Containerization
Cross-Compilation (Recommended on Apple Silicon)
Go's built-in cross-compilation is simpler and more reliable than Docker multi-stage builds on Apple Silicon:
# Build for Linux from Mac
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o app-linux-amd64 .
# Build for multiple platforms
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app-amd64 .
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o app-arm64 .
Why native cross-compilation?
- Docker buildx QEMU emulation segfaults with Go 1.24+ on Apple Silicon
- Go's cross-compiler is fast and reliable
- No Docker needed for the compilation step
Dockerfile Pattern (Pre-Built Binary)
FROM alpine:latest
WORKDIR /app
COPY app-linux-amd64 ./app
RUN chmod +x ./app && addgroup -S app && adduser -S app -G app
USER app
CMD ["./app"]
Build and push:
docker buildx build --platform linux/amd64 -t myregistry/myapp:latest --push .
When to Use Multi-Stage Builds
Multi-stage Docker builds (compile inside Docker) still work for:
- CI/CD on Linux runners
- ARM64-to-ARM64 builds on Apple Silicon
- When you need reproducible builds without local Go installation
But avoid multi-stage with --platform linux/amd64 on Apple Silicon Macs.
Version Info
- Go: 1.25 (latest stable)
- golangci-lint: v2.8+ (uses formatters section for goimports)
- Skill Updated: January 2026
Source
git clone https://github.com/DigitalPine/claude-skills/blob/main/plugins/golang/skills/golang/SKILL.mdView on GitHub Overview
This skill helps you start new Go projects quickly or audit and upgrade existing ones. It offers two tiers: Quick Start for rapid prototyping and Full Setup for production-ready setups, with guided linting, structure, and tooling.
How This Skill Works
Choose between Quick Start and Full Setup. Quick Start gives a fast, 5-step path to a running project with essential tooling and a minimal config. Full Setup expands the structure, upgrades tooling and builds, and includes an Audit Mode to progressively fix issues in existing codebases.
When to Use It
- Create a new Go project
- Set up a Go CLI/API/library
- Audit this Go project
- Add linting to my Go project
- Upgrade an existing project to production-ready setup
Quick Start
- Step 1: Initialize project and module: mkdir myproject && cd myproject; go mod init github.com/yourorg/myproject
- Step 2: Install essential tooling and copy minimal configs: go get -tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest; go install github.com/air-verse/air@latest
- Step 3: Create entry point and verify: add main.go with a simple run() and run make lint, make test, make dev
Best Practices
- Start with Quick Start for speed, then graduate to Full Setup as the project grows or the team expands
- Follow the provided assets and references to structure your project
- Keep linting and tests integrated (make lint, make test) during development
- Migrate gradually: upgrade go.mod, tooling, and Makefile in stages
- Use Audit Mode to address critical issues before nicer-to-have improvements
Example Use Cases
- Bootstrapping a new CLI tool with fast feedback loop
- Turning a prototype into a production-ready API library
- Auditing an existing Go project to unblock shipping
- Adding and standardizing linting across a Go codebase
- Refactoring a small repo into a structured multi-package layout