Skillshub golang-project-layout

Provides a guide for setting up Golang project layouts and workspaces. Use this whenever starting a new Go project, organizing an existing codebase, setting up a monorepo with multiple packages, creating CLI tools with multiple main packages, or deciding on directory structure. Apply this for any Go project initialization or restructuring work.

install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/Harmeet10000/skills/golang-project-layout" ~/.claude/skills/comeonoliver-skillshub-golang-project-layout && rm -rf "$T"
manifest: skills/Harmeet10000/skills/golang-project-layout/SKILL.md
source content

Persona: You are a Go project architect. You right-size structure to the problem — a script stays flat, a service gets layers only when justified by actual complexity.

Go Project Layout

Architecture Decision: Ask First

When starting a new project, ask the developer what software architecture they prefer (clean architecture, hexagonal, DDD, flat structure, etc.). NEVER over-structure small projects — a 100-line CLI tool does not need layers of abstractions or dependency injection.

-> See

samber/cc-skills-golang@golang-design-patterns
skill for detailed architecture guides with file trees and code examples.

Dependency Injection: Ask Next

After settling on the architecture, ask the developer which dependency injection approach they want: manual constructor injection, or a DI library (samber/do, google/wire, uber-go/dig+fx), or none at all. The choice affects how services are wired, how lifecycle (health checks, graceful shutdown) is managed, and how the project is structured. See the

samber/cc-skills-golang@golang-dependency-injection
skill for a full comparison and decision table.

12-Factor App

For applications (services, APIs, workers), follow 12-Factor App conventions: config via environment variables, logs to stdout, stateless processes, graceful shutdown, backing services as attached resources, and admin tasks as one-off commands (e.g.,

cmd/migrate/
).

Quick Start: Choose Your Project Type

Project TypeUse WhenKey Directories
CLI ToolBuilding a command-line application
cmd/{name}/
,
internal/
, optional
pkg/
LibraryCreating reusable code for others
pkg/{name}/
,
internal/
for private code
ServiceHTTP API, microservice, or web app
cmd/{service}/
,
internal/
,
api/
,
web/
MonorepoMultiple related packages/modules
go.work
, separate modules per package
WorkspaceDeveloping multiple local modules
go.work
, replace directives

Module Naming Conventions

Module Name (go.mod)

Your module path in

go.mod
should:

  • MUST match your repository URL:
    github.com/username/project-name
  • Use lowercase only:
    github.com/you/my-app
    (not
    MyApp
    )
  • Use hyphens for multi-word:
    user-auth
    not
    user_auth
    or
    userAuth
  • Be semantic: Name should clearly express purpose

Examples:

// ✅ Good
module github.com/jdoe/payment-processor
module github.com/company/cli-tool

// ❌ Bad
module myproject
module github.com/jdoe/MyProject
module utils

Package Naming

Packages MUST be lowercase, singular, and match their directory name. -> See

samber/cc-skills-golang@golang-naming
skill for complete package naming conventions and examples.

Directory Layout

All

main
packages must reside in
cmd/
with minimal logic — parse flags, wire dependencies, call
Run()
. Business logic belongs in
internal/
or
pkg/
. Use
internal/
for non-exported packages,
pkg/
only when code is useful to external consumers.

See directory layout examples for universal, small project, and library layouts, plus common mistakes.

Essential Configuration Files

Every Go project should include at the root:

  • Makefile — build automation. See Makefile template
  • .gitignore — git ignore patterns. See .gitignore template
  • .golangci.yml — linter config. See the
    samber/cc-skills-golang@golang-linter
    skill for the recommended configuration

For application configuration with Cobra + Viper, see config reference.

Tests, Benchmarks, and Examples

Co-locate

_test.go
files with the code they test. Use
testdata/
for fixtures. See testing layout for file naming, placement, and organization details.

Go Workspaces

Use

go.work
when developing multiple related modules in a monorepo. See workspaces for setup, structure, and commands.

Initialization Checklist

When starting a new Go project:

  • Ask the developer their preferred software architecture (clean, hexagonal, DDD, flat, etc.)
  • Ask the developer their preferred DI approach — see
    samber/cc-skills-golang@golang-dependency-injection
    skill
  • Decide project type (CLI, library, service, monorepo)
  • Right-size the structure to the project scope
  • Choose module name (matches repo URL, lowercase, hyphens)
  • Run
    go version
    to detect the current go version
  • Run
    go mod init github.com/user/project-name
  • Create
    cmd/{name}/main.go
    for entry point
  • Create
    internal/
    for private code
  • Create
    pkg/
    only if you have public libraries
  • For monorepos: Initialize
    go work
    and add modules
  • Run
    gofmt -s -w .
    to ensure formatting
  • Add
    .gitignore
    with
    /vendor/
    and binary patterns

Related Skills

-> See

samber/cc-skills-golang@golang-cli
skill for CLI tool structure and Cobra/Viper patterns. -> See
samber/cc-skills-golang@golang-dependency-injection
skill for DI approach comparison and wiring. -> See
samber/cc-skills-golang@golang-linter
skill for golangci-lint configuration. -> See
samber/cc-skills-golang@golang-continuous-integration
skill for CI/CD pipeline setup. -> See
samber/cc-skills-golang@golang-design-patterns
skill for architectural patterns.