Skip to content

The "Don't be Java Bro :-)" framing in robs the overall standards document of credibility by making light of a contentious issue #278

@AlexChesser

Description

@AlexChesser

This section should be fixed:

https://github.com/golang-standards/project-layout?tab=readme-ov-file#src


/src

Some Go projects do have a src folder, but it usually happens when the devs came from the Java world where it's a common pattern. If you can help yourself try not to adopt this Java pattern. You really don't want your Go code or Go projects to look like Java :-)

Don't confuse the project level /src directory with the /src directory Go uses for its workspaces as described in How to Write Go Code. The $GOPATH environment variable points to your (current) workspace (by default it points to $HOME/go on non-windows systems). This workspace includes the top level /pkg, /bin and /src directories. Your actual project ends up being a sub-directory under /src, so if you have the /src directory in your project the project path will look like this: /some/path/to/workspace/src/your_project/src/your_code.go. Note that with Go 1.11 it's possible to have your project outside of your GOPATH, but it still doesn't mean it's a good idea to use this layout pattern.


Reasons This Framing Is Bad

  • It's an Ad Hominem Attack: The argument dismisses a technical pattern by attacking the perceived background of the developers who use it ("came from the Java world"). A person's background is irrelevant to the technical merit of a decision.
  • It Uses Unprofessional "Tribalism": The phrase "You really don't want your Go code or Go projects to look like Java :-)" is a subjective, aesthetic argument. It promotes an "us vs. them" mentality instead of providing a technical reason why the pattern is suboptimal for Go.
  • It Lacks a Clear Technical Justification: The core technical reason to avoid /src in modern Go is that it creates longer, less idiomatic import paths (e.g., repo/src/pkg instead of repo/pkg). The provided text buries this point in a confusing and outdated explanation of GOPATH, which is less relevant in a world with Go Modules.
  • It Ignores a Legitimate Rationale: The argument fails to acknowledge the real-world desire to separate all files required to build the package from non-code assets that support development, deployment, or documentation. By dismissing the /src folder as merely a "Java pattern," it overlooks its practical use as a tool for organizing a repository and creating a clear distinction between compilable source and other project files.
  • It's Gatekeeping: The tone can make developers new to Go, especially those from a Java background, feel unwelcome. Technical standards should be inclusive and educational, not dismissive.

Alternative

/src

In modern Go projects, a top-level /src directory is generally not recommended. With Go Modules, the directory containing the go.mod file acts as the module root. Omitting the /src folder leads to shorter, cleaner import paths (e.g., github.com/user/project/package) that align directly with the repository's structure.

Alternative 2:

Grouping Your Go Source Code

While separating source code into a dedicated directory is a good practice, using the name /src is a holdover from Go's older GOPATH system that creates non-standard import paths.

A more idiomatic solution is to place all your application's private Go code inside the special /internal directory. The go.mod file still lives in the repository root to define the module, while the Go toolchain enforces that packages within /internal can only be used by your application. This cleanly separates your Go source from other repository files like scripts and deployment configurations.

This structure provides the desired organization while aligning with modern Go conventions.

/my-project           <-- Repository root
├── go.mod            <-- Module root
├── internal/         <-- All Go source code
│   ├── cmd/
│   │   └── my-app/
│   └── api/
├── other_folders/    <-- Any folders or files not required to build the project
├── scripts/
└── deploy/

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions