agentleFS
aiproxeraiproxer/aiproxer/.agents/skills/golang-project-layout/SKILL.md

golang-project-layout

Skill22 starsChanged 16 days agoMITView on GitHub

Design and review Go package/module boundaries, internal visibility, commands, generated sources, workspaces, fixtures, builds, and release structure.

13 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use golang-samber-mo, golang-samber-ro and 7 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • guynhsichngeodiecSkill

    golang-samber-mo

    Monadic types for Golang using samber/mo — Option, Result, Either, Future, IO, Task, and State types for type-safe nullable values, error handling, and functional composition with pipeline sub-packages. Apply when using or adopting samber/mo, when the codebase imports `github.com/samber/mo`, or when considering functional programming patterns as a safety design for Golang.

    Also in 7 projects that use this

  • guynhsichngeodiecSkill

    golang-samber-ro

    Reactive streams and event-driven programming in Golang using samber/ro — ReactiveX implementation with 150+ type-safe operators, cold/hot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron, fsnotify, JSON, logging), automatic backpressure, error propagation, and Go context integration. Apply when using or adopting samber/ro, when the codebase imports github.com/samber/ro, or when building asynchronous event-driven pipelines, real-time data processing, streams, or reactive architectures in Go. Not for finite slice transforms (-> See golang-samber-lo skill).

    Also in 7 projects that use this

  • alexastrumSkill

    golang-google-wire

    Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wire_gen.go. Apply when using or adopting google/wire, when the codebase imports `github.com/google/wire`, or when wiring an application graph at compile time via `wire.Build`. For runtime DI with reflection, see `samber/cc-skills-golang@golang-uber-dig` skill.

    Also in 6 projects that use this

  • alexastrumSkill

    golang-graphql

    Implements GraphQL APIs in Golang using gqlgen or graphql-go. Apply when building GraphQL servers, designing schemas, writing resolvers, handling subscriptions, or integrating GraphQL with existing Go HTTP services. Also apply when the codebase imports `github.com/99designs/gqlgen` or `github.com/graph-gophers/graphql-go`.

    Also in 6 projects that use this

  • +3 more from guynhsichngeodiec
  • +2 more from alexastrum

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 6 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 13 edited versions we read keep these.

  • 6

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Check internal visibility using its parent tree, import cycles, package names, generated sources, and build constraints across supported …

    line 15
  2. Distinctive:

    Verify each nested module independently of go.work.

    line 17
  3. Distinctive:

    Keep main thin when there is substantial business logic: parse configuration, construct dependencies, run the application, and handle …

    line 35
  4. Distinctive:

    keep commands and orchestration thin where that improves testing.

    line 59
  5. Very specific:

    add internal only for a real visibility boundary.

    line 60
  6. Very specific:

    place tests/fixtures/generated code predictably.

    line 61
  7. Distinctive:

    document workspace and replacement behavior.

    line 62
  8. Very specific:

    run gofmt, go test, go vet, and repository-specific checks.

    line 63
  9. Distinctive:

    avoid introducing a framework or DI library before its lifecycle and maintenance benefits are demonstrated.

    line 64

“Common” is measured: kept by at least 6 in 10 of the 13 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Go project layout

Choose structure from the project's users, deployment units, and expected reuse. A small command may be one package; a service or library may need boundaries that can be tested independently. The directory names below are conventions and tools, not language requirements.

Focused review

For a review, keep the work read-only unless fixes are requested. Establish the review base, supported versions, and relevant contract; inspect changed code plus the callers and tests needed to assess it. Stay within this skill’s lens.

  • Map package/import edges, ownership, public consumers, executable boundaries, and module release units before proposing directory moves.
  • Check internal visibility using its parent tree, import cycles, package names, generated sources, and build constraints across supported platforms.
  • Trace moved paths through embed directives, fixtures, migration loaders, scripts, Docker contexts, CI/release jobs, and external import compatibility.
  • Verify each nested module independently of go.work. A different layout is a finding only when it resolves a demonstrated coupling, ownership, build, or release problem.

Report each actionable finding with severity, confidence, file/symbol, trigger, consequence, and smallest remedy. Separate introduced/worsened defects from pre-existing debt, and state executed checks versus inference. If none survives validation, say so and identify coverage gaps.

Decide the boundaries

Identify the module or modules, public API, executable entry points, generated code, deployment artifacts, and test fixtures. Keep dependencies directed toward stable contracts and put orchestration at the application boundary. Add a package when it gives a useful ownership or API boundary, not merely to create more files.

Common choices:

NeedPossible layout
One small commandgo.mod, main.go, adjacent tests and docs.
Several commandscmd/<name>/main.go plus shared packages; cmd/ is a convention, not a requirement.
Reusable libraryRoot or named public package; internal/ for implementation details.
ServiceCommand entry point, internal transport/application/domain packages, migrations/config as needed.
Multiple modulesSeparate go.mod files and an optional go.work for local development.

Keep main thin when there is substantial business logic: parse configuration, construct dependencies, run the application, and handle shutdown. A flat package is appropriate when that is clearer.

Module and package rules

Choose a module path that matches how consumers fetch it when the module is published; private modules can use the organization's configured path. Lowercase import paths are conventional and ordinary module paths at major versions >=2 require a /vN suffix; gopkg.in uses its supported .vN convention. Avoid a generic utils package and name packages for the domain they own. Package names normally match the directory's package declaration but need not mirror every repository folder.

internal visibility is defined by the parent directory tree: code can import an internal package only from within the tree rooted at its parent. It is not simply “private to the module.” pkg/ is also a convention; use it only when it communicates a stable public boundary in this repository.

Tests, fixtures, and generated files

Keep tests near the code they exercise. Any _test.go file is recognized by Go; names such as _bench_test.go or _example_test.go are optional organizational conventions. Benchmark and example function names (BenchmarkX, ExampleX) determine discovery. Keep external fixtures in testdata/ when they should not be imported as packages, and clearly mark generated files and their command/version.

Modules and workspaces

Use one module for one release/versioning boundary unless independent modules are genuinely needed. Use go.work to develop related modules together, but test each module with GOWORK=off before publishing so local replacements do not hide missing requirements. Document whether go.work and go.work.sum are committed or ignored according to repository policy.

Configuration and repository files

Add only files the project uses. A Makefile, .gitignore, linter config, CI workflows, Dockerfile, and release config are useful when their commands are real and documented; none is required by Go. Keep configuration precedence explicit (defaults, config files, environment, flags, or application-specific overrides) and validate it at startup. See config.

Initialization checklist

  • define the public API and deployment boundaries;
  • choose a module path and Go version deliberately;
  • keep commands and orchestration thin where that improves testing;
  • add internal only for a real visibility boundary;
  • place tests/fixtures/generated code predictably;
  • document workspace and replacement behavior;
  • run gofmt, go test, go vet, and repository-specific checks;
  • avoid introducing a framework or DI library before its lifecycle and maintenance benefits are demonstrated.

See directory layouts, testing layout, workspaces, and configuration.

Related local skills: golang-cli, golang-design-patterns, golang-dependency-management, golang-testing, and golang-code-style.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.