Just a few weeks until the 2021 JavaScript Full-Stack Bootcamp opens.
Signup to the waiting list!

## Folder structure

Go projects are composed by packages. We call commands the packages that have the main identifier.

A project can have

• 1 package
• n packages
• 1 command
• 1 command and 1 package
• n commands and 1 package
• 1 command and n packages
• n commands and n packages

Depending on the nature of your project you need to organize the folder structure in a certain way.

### Some real world examples

Let’s see some real world examples of this in the wild, here below. I took them from Five suggestions for setting up a Go project by Dave Cheney.

#### Example of a project with 1 package:

https://github.com/kr/fs

#### Example of a project with n packages

https://github.com/pkg/term

#### Example of a project with 1 command

https://github.com/tools/godep

#### Example of a project with 1 command and 1 package

https://github.com/monochromegane/the_platinum_searcher

#### Example of a project with n commands and n packages

https://github.com/golang/tools

### Conventions for file structure inside a project

From those examples we can tell these conventions:

If you have one command, it can live in a main.go file in the root of the project.

With more than one command, create a cmd/ folder, and under this, create a folder with the name of the command. In each folder, ideally a .go file with the same name will contain the main() function, although it’s not mandatory.

Packages go in their own folder, unless you just have one package.

## Filesystem location for installed packages

Any Go project can be installed by using go get. go get will install packages under $GOPATH/src. For example typing go get github.com/kr/fs will download and install the 1-package repo located at https://github.com/kr/fs, and it will put it under $GOPATH/src/github.com/kr/fs. We can just reference it in our programs using import github.com/kr/fs.

What if we type

go get github.com/tools/godep

instead? Remember, this is the one-command repository we listed before.

go get will download it like it did for github.com/kr/fs, and put it under $GOPATH/src, BUT since it’s a command, it will also compile and create a $GOPATH/bin/godep binary.

Go commands are compiled to the name of the enclosing folder, in this case the folder was the root one, so it’s godep. In the case of multiple commands, it will take the last subfolder name. E.g. an ideal github.com/flaviocopes/tools/cmd/unzip would be compiled to unzip. It does not take the name of the file containing the main() function.

## Workspaces

Go has a quite unique concept of workspace. A workspace is the folder structure that $GOPATH points to. When you create a new workspace, add the $GOPATH/bin folder to your path as well. For example if you want to set your workspace to ~/go (which by the ways is the default):

export GOPATH=~/go
export PATH=~/go/bin:$PATH Now, any Go code you run will reference this folder. This allows you to create separate workspaces, although as stated in the official docs, Go programmers typically keep all their Go code in a single workspace. Note that this differs from other programming environments in which every project has a separate workspace and workspaces are closely tied to version control repositories. This is an example of a workspace, listed in the official docs:  bin/ hello # command executable outyet # command executable pkg/ linux_amd64/ github.com/golang/example/ stringutil.a # package object src/ github.com/golang/example/ .git/ # Git repository metadata hello/ hello.go # command source outyet/ main.go # command source main_test.go # test source stringutil/ reverse.go # package source reverse_test.go # test source golang.org/x/image/ .git/ # Git repository metadata bmp/ reader.go # package source writer.go # package source #... (many more repositories and packages omitted) ... Knowing this, let’s see.. ## Where to place your commands and packages When running commands using go run, you can have your project anywhere you like, but this is an approach useful only for quick testing. You should create your programs inside the $GOPATH/src folder, with your unique namespace, e.g.

$GOPATH/src/github.com/flaviocopes/hello When running (from anywhere in the system) go install github.com/flaviocopes/hello Go will compile and put the hello binary in $GOPATH/bin, ready to be run from anywhere in the system.

The same goes for packages, except that when running go install, it will put the compiled package under \$GOPATH/pkg.

## Reference

The 2021 JavaScript Full-Stack Bootcamp will start at the end of March 2021. Don't miss this opportunity, signup to the waiting list!