Skill
Community

module-conventions

Install
1
Install the plugin
$
npx claudepluginhub jsamuelsen11/claude-config --plugin ccfg-golang

Want just this skill?

Then install: npx claudepluginhub u/[userId]/[slug]

Description

This skill should be used when creating or editing go.mod, managing Go dependencies, configuring Go modules, or organizing Go packages and module boundaries.

Tool Access

This skill uses the workspace's default tool permissions.

Skill Content

Go Module Conventions and Dependency Management

This skill defines best practices for Go module management, dependency handling, package organization, and versioning following the Go modules system.

Module Path Configuration

Use Full Repository Path

The module path in go.mod must be the full import path, typically matching the repository URL.

// CORRECT: Full repository path
module github.com/username/myproject

go 1.21

require (
    github.com/pkg/errors v0.9.1
)
// WRONG: Incomplete or incorrect module path
module myproject  // Missing domain and path

module example.com/myproject  // Don't use example.com for real projects

Module Path for Private Repositories

For private repositories, use the full Git hosting path with authentication configured.

// CORRECT: Private repository module path
module github.com/mycompany/private-repo

go 1.21
# Configure Git for private repos
git config --global url."git@github.com:".insteadOf "https://github.com/"

# Or use GOPRIVATE environment variable
export GOPRIVATE=github.com/mycompany/*
# .netrc for private repos with HTTPS
machine github.com
login USERNAME
password TOKEN

Go Version Management

Specify Minimum Go Version in go.mod

Always specify the minimum Go version required by your module in go.mod.

// CORRECT: Explicit Go version
module github.com/username/myproject

go 1.21  // Minimum version required

require (
    github.com/stretchr/testify v1.8.4
)
// WRONG: Missing or vague version
module github.com/username/myproject

// No go version specified - bad practice

Use .go-version for Toolchain Pinning

Use .go-version file to pin the exact Go toolchain version for development.

# CORRECT: .go-version file
1.21.5
# Tools like goenv or asdf read .go-version
asdf install golang
goenv install
// go.mod specifies minimum
go 1.21

// .go-version specifies exact version for dev
// 1.21.5

Toolchain Directive for Go 1.21+

Use the toolchain directive to specify the Go toolchain version.

// CORRECT: Toolchain directive
module github.com/username/myproject

go 1.21

toolchain go1.21.5

Dependency Management

Run go mod tidy Regularly

Always run go mod tidy to clean up dependencies and ensure go.mod and go.sum are in sync.

# CORRECT: Regular go mod tidy workflow
go mod tidy        # Remove unused and add missing dependencies
go mod verify      # Verify checksums
# In CI, verify go.mod is tidy
go mod tidy
git diff --exit-code go.mod go.sum || (echo "go.mod is not tidy" && exit 1)
# Taskfile.yml task
tasks:
  tidy:
    desc: Tidy and verify dependencies
    cmds:
      - go mod tidy
      - go mod verify
      - go mod download

Use go mod verify for Security

Verify dependency checksums to ensure integrity.

# CORRECT: Verify dependencies
go mod verify
# WRONG: Skipping verification
go build  # Builds without verification
# In CI pipeline
- name: Verify dependencies
  run: |
    go mod download
    go mod verify

Use go mod why to Understand Dependencies

Use go mod why to understand why a dependency is required.

# CORRECT: Understanding dependency tree
go mod why github.com/pkg/errors

# Output shows dependency chain:
# github.com/username/myproject
# github.com/username/myproject/internal/service
# github.com/pkg/errors
# Find all dependencies of a package
go mod graph | grep github.com/pkg/errors

# Show dependency tree
go mod graph

Upgrade Dependencies Carefully

Use go get to upgrade dependencies with version constraints.

# CORRECT: Controlled dependency upgrades
go get github.com/stretchr/testify@latest       # Latest version
go get github.com/stretchr/testify@v1.8.4       # Specific version
go get github.com/stretchr/testify@v1           # Latest v1.x.x
go get -u ./...                                  # Upgrade all dependencies
go get -u=patch ./...                            # Upgrade to latest patch versions
# WRONG: Uncontrolled upgrades
go get -u  # Upgrades everything, can break builds
# Best practice: Test after upgrade
go get -u=patch ./...
go mod tidy
go test ./...

Replace Directives

Replace Only for Local Development

Use replace directives only for local development, never commit local filesystem paths.

// CORRECT: Replace for local development (don't commit)
module github.com/username/myproject

go 1.21

require (
    github.com/username/library v1.2.3
)

// Uncomment for local development only
// replace github.com/username/library => ../library
// WRONG: Committed local replace directive
module github.com/username/myproject

go 1.21

replace github.com/username/library => /Users/john/projects/library  // Never commit this!

Replace for Forked Dependencies

Use replace to use a fork or specific commit of a dependency.

// CORRECT: Replace with fork
module github.com/username/myproject

go 1.21

require (
    github.com/original/library v1.2.3
)

// Use fork with bug fix
replace github.com/original/library => github.com/username/library-fork v1.2.4-fix
# Replace with specific commit
go mod edit -replace=github.com/original/library=github.com/username/library-fork@commit-hash

Document Replace Directives

Always document why a replace directive exists.

// CORRECT: Documented replace
module github.com/username/myproject

go 1.21

require (
    github.com/problematic/library v1.0.0
)

// Replace with fork that fixes critical security issue CVE-2024-1234
// TODO: Remove when upstream merges fix (tracking issue: #123)
replace github.com/problematic/library => github.com/username/library-fixed v1.0.1-patched

Package Organization

Use cmd Directory for Entry Points

Place all executable entry points in cmd/ directory with subdirectories for each binary.

# CORRECT: cmd structure for multiple binaries
myproject/
  cmd/
    server/
      main.go
    worker/
      main.go
    migrate/
      main.go
  internal/
    service/
      user.go
  pkg/
    client/
      client.go
  go.mod
// CORRECT: cmd/server/main.go
package main

import (
    "log"
    "myproject/internal/service"
)

func main() {
    svc := service.New()
    log.Fatal(svc.Start())
}
# WRONG: Binaries in root or mixed structure
myproject/
  main.go           # Don't put main in root for libraries
  server.go
  worker.go

Use internal for Private Code

Use internal/ directory for code that should not be importable by external modules.

# CORRECT: internal directory structure
myproject/
  internal/
    service/
      user.go       # Cannot be imported by external modules
    repository/
      postgres.go
    middleware/
      auth.go
  pkg/
    client/
      client.go     # Public API
  go.mod
// CORRECT: Internal package
package service  // In internal/service/user.go

// This package cannot be imported by modules outside myproject
type UserService struct {
    repo Repository
}
// WRONG: Putting private code in pkg/
// pkg/internals/service.go
package internals  // Don't use "internals" in pkg/

// Still importable by external modules, defeating the purpose

Use pkg for Public Libraries

Use pkg/ directory for code intended to be imported by external modules.

# CORRECT: pkg for public API
myproject/
  pkg/
    client/
      client.go     # Public client library
    types/
      user.go       # Public types
  internal/
    service/
      impl.go       # Private implementation
  go.mod
// CORRECT: pkg/client/client.go
package client

// Client is the public API for external users
type Client struct {
    baseURL string
}

// NewClient creates a new client instance
func NewClient(baseURL string) *Client {
    return &Client{baseURL: baseURL}
}

Versioning and Releases

Use Semantic Versioning with v Prefix

Follow semantic versioning with v prefix for Git tags.

# CORRECT: Semantic versioning tags
git tag v1.0.0
git tag v1.1.0
git tag v1.1.1
git tag v2.0.0

git push origin v1.0.0
# WRONG: Missing v prefix or non-semver
git tag 1.0.0      # Missing 'v' prefix
git tag release-1  # Not semantic versioning
# Create and push version tag
git tag -a v1.2.3 -m "Release version 1.2.3"
git push origin v1.2.3

# List all version tags
git tag -l "v*"

Major Version v2+ Module Path Suffix

For v2 and higher, add version suffix to module path.

// CORRECT: v2 module path
module github.com/username/myproject/v2

go 1.21

require (
    github.com/stretchr/testify v1.8.4
)
// Import v2 module
import "github.com/username/myproject/v2/pkg/client"
# Create v2 tag
git tag v2.0.0
git push origin v2.0.0
// WRONG: v2 without path suffix
module github.com/username/myproject  // Should be /v2

go 1.21

Pre-release Versions

Use pre-release suffixes for unstable versions.

# CORRECT: Pre-release versions
git tag v1.0.0-alpha.1
git tag v1.0.0-beta.1
git tag v1.0.0-rc.1
git tag v1.0.0  # Final release
# Use pre-release in go.mod
require github.com/username/library v1.0.0-beta.1

Vendoring

Prefer Module Proxy Over Vendoring

Use Go module proxy instead of vendoring when possible.

# CORRECT: Configure module proxy
export GOPROXY=https://proxy.golang.org,direct
export GOSUMDB=sum.golang.org
# Private modules bypass proxy
export GOPRIVATE=github.com/mycompany/*

Vendor Only for Reproducibility

Use vendoring only when necessary for hermetic builds.

# CORRECT: Vendor when needed
go mod vendor

# Verify vendor is up to date
go mod vendor
git diff --exit-code vendor/
# Usually don't commit vendor/
vendor/

# But commit vendor/ if required for build reproducibility
# Build with vendor
go build -mod=vendor ./cmd/server
# WRONG: Vendoring by default
go mod vendor  # Don't vendor unless necessary

Multi-Module Repositories

Avoid Multi-Module Repos When Possible

Prefer single module per repository for simplicity.

# CORRECT: Single module (preferred)
myproject/
  cmd/
  internal/
  pkg/
  go.mod
# Use multi-module only with clear separation
monorepo/
  service-a/
    go.mod
    cmd/
    internal/
  service-b/
    go.mod
    cmd/
    internal/

Use Go Workspaces for Multi-Module Development

Use go.work for local development of multiple modules.

# CORRECT: Initialize workspace
go work init ./service-a ./service-b
// go.work (don't commit to version control)
go 1.21

use (
    ./service-a
    ./service-b
)
# CORRECT: Ignore workspace file
go.work
go.work.sum
# Work with modules in workspace
cd service-a
go test ./...  # Uses workspace configuration

# Sync workspace
go work sync

Indirect Dependencies

Understand Indirect Dependencies

Indirect dependencies appear in go.mod when required by direct dependencies.

// CORRECT: Indirect dependencies marked
module github.com/username/myproject

go 1.21

require (
    github.com/direct/dependency v1.2.3
)

require (
    github.com/indirect/dependency v2.1.0 // indirect
)
# View all dependencies
go list -m all

# View dependency tree
go mod graph

Clean Up Unused Indirect Dependencies

Run go mod tidy to remove unused indirect dependencies.

# CORRECT: Remove unused dependencies
go mod tidy

# Check which module requires a dependency
go mod why github.com/indirect/dependency

Module Download and Caching

Configure Module Cache

Understand and configure Go module cache location.

# Default cache location
go env GOMODCACHE
# Output: /home/user/go/pkg/mod

# Set custom cache location
export GOMODCACHE=/custom/path
# Download all dependencies
go mod download

# Download specific module
go mod download github.com/stretchr/testify
# Clear module cache
go clean -modcache

Use Module Cache in CI

Configure CI to cache module downloads for faster builds.

# CORRECT: GitHub Actions module caching
- name: Setup Go
  uses: actions/setup-go@v4
  with:
    go-version: '1.21'
    cache: true # Automatically caches modules

- name: Download dependencies
  run: go mod download
# GitLab CI module caching
cache:
  paths:
    - .go/pkg/mod

before_script:
  - export GOMODCACHE=$CI_PROJECT_DIR/.go/pkg/mod
  - go mod download

Module Checksums and Security

Commit go.sum to Version Control

Always commit go.sum for dependency verification.

# CORRECT: Don't ignore go.sum
# go.mod and go.sum should be committed

# WRONG: Ignoring go.sum
go.sum  # Never add this to .gitignore!
# Verify go.sum is committed
git add go.mod go.sum
git commit -m "chore: update dependencies"

Use GOSUMDB for Verification

Configure checksum database for security.

# CORRECT: Use public checksum database
export GOSUMDB=sum.golang.org

# Disable for private modules
export GONOSUMDB=github.com/mycompany/*
# Verify all dependencies
go mod verify

Module-Aware Commands

Use Module-Aware go get

Understand go get behavior in module mode.

# CORRECT: Module-aware go get
go get github.com/stretchr/testify@latest      # Add or upgrade
go get github.com/stretchr/testify@v1.8.4      # Specific version
go get github.com/stretchr/testify@none        # Remove dependency
# WRONG: Old GOPATH-style go get
export GO111MODULE=off  # Don't disable modules
go get github.com/stretchr/testify  # Unclear semantics

Use go install for Tools

Use go install for installing command-line tools.

# CORRECT: Install tools with go install
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install mvdan.cc/gofumpt@latest
go install go.uber.org/mock/mockgen@latest
# WRONG: Using go get for tools
go get github.com/golangci/golangci-lint/cmd/golangci-lint  # Old way
// Track tool dependencies in tools.go
//go:build tools

package tools

import (
    _ "github.com/golangci/golangci-lint/cmd/golangci-lint"
    _ "mvdan.cc/gofumpt"
    _ "go.uber.org/mock/mockgen"
)

Best Practices Summary

Module Initialization Checklist

When creating a new Go module, follow this checklist.

# CORRECT: Initialize new module
mkdir myproject
cd myproject

# Initialize module
go mod init github.com/username/myproject

# Set Go version
go mod edit -go=1.21

# Create basic structure
mkdir -p cmd/myapp internal pkg

# Create .go-version
echo "1.21.5" > .go-version

# Create .gitignore
cat > .gitignore <<EOF
# Binaries
bin/
*.exe

# Go workspace
go.work
go.work.sum

# IDE
.idea/
.vscode/
*.swp
EOF

# Initialize git
git init
git add .
git commit -m "chore: initialize Go module"

Dependency Update Workflow

Regular dependency maintenance workflow.

# CORRECT: Dependency update process
# 1. Check for updates
go list -u -m all

# 2. Update patch versions
go get -u=patch ./...

# 3. Test changes
go test ./...

# 4. Tidy dependencies
go mod tidy

# 5. Verify checksums
go mod verify

# 6. Check for vulnerabilities
govulncheck ./...

# 7. Commit changes
git add go.mod go.sum
git commit -m "chore: update dependencies"

This skill ensures proper Go module management, dependency handling, and package organization following the Go team's recommendations and community best practices.

Stats
Stars0
Forks0
Last CommitFeb 9, 2026

Similar Skills