Question

What Does go install Do in Go? Build vs Install Explained

Question

The Go documentation does not clearly explain the difference between go build and go install.

I expected go install to behave like make install: compile a program and place the final executable in a system location such as /usr/local/bin/my_new_toy. Instead, it appears to place binaries in GOROOT/bin.

What does go install actually do? Can I configure Go to install an executable somewhere else, or should I use a Makefile?

Short Answer

You will learn the difference between go build and go install, where Go installs command-line executables, how GOBIN and GOPATH affect the destination, and when directly choosing an output path is more appropriate.

Concept

go build and go install both compile Go code, but they have different goals.

  • go build compiles a package. For a command package (package main), it normally writes an executable to the current directory. You can also choose an output path with -o.
  • go install compiles a package and installs command executables into Go's binary installation directory.

For a command, the installation directory is determined in this order:

  1. GOBIN, if it is set.
  2. $GOPATH/bin, if GOBIN is not set.

On a typical current Go installation, go install does not install your application into GOROOT/bin. GOROOT is where the Go toolchain itself lives. It may contain tools such as go and gofmt, but it is not the normal destination for programs you develop.

For example, if your GOPATH is /home/alex/go, this command:

go install ./cmd/my_new_toy

installs the executable at:

/home/alex/go/bin/my_new_toy

This behavior matters because Go keeps developer-installed tools separate from system-managed executables. You can add the Go binary directory to your PATH and run installed commands from any directory.

Mental Model

Think of go build as preparing a finished item on your workbench. It compiles the program, and the executable is available where you are working.

Think of go install as putting a finished command into your personal tool drawer. The drawer is GOBIN or $GOPATH/bin, a predictable place where command-line tools can be stored and found later through PATH.

GOROOT is different: it is the factory that contains Go itself. Your own tools generally should not be placed there.

Take Quiz

Syntax and Examples

Compile a command in the current project:

go build ./cmd/my_new_toy

If ./cmd/my_new_toy is a package main, Go creates an executable named my_new_toy in the current directory by default.

Install the command into Go's binary directory:

go install ./cmd/my_new_toy

Check the configured locations:

go env GOBIN GOPATH GOROOT

If GOBIN is empty, determine the default install directory with:

go env GOPATH

The executable is installed under that path's bin directory.

Use a custom Go install directory

Set GOBIN to an absolute path:

export GOBIN="$HOME/.local/bin"
go install ./cmd/my_new_toy

The binary will be written to:

$HOME/.local/bin/my_new_toy

Make sure the directory is on your PATH:

export PATH="$HOME/.local/bin:$PATH"

Choose an exact output file

When you need a particular destination, use go build -o:

go build -o /usr/local/bin/my_new_toy ./cmd/my_new_toy

Writing to /usr/local/bin commonly requires administrator permission:

sudo go build -o /usr/local/bin/my_new_toy ./cmd/my_new_toy

For deployment, it is often better to build into a temporary or release directory first, then copy the executable using the deployment process.

Step by Step Execution

Consider this project layout:

example.com/toys
└── cmd
    └── greet
        └── main.go

cmd/greet/main.go:

package main

import "fmt"

func main() {
	fmt.Println("Hello!")
}

Run:

go install ./cmd/greet

What happens:

  1. Go reads the package at ./cmd/greet.
  2. It sees package main, so this package produces an executable.
  3. Go compiles the package and its dependencies. Previously compiled dependency results may be reused from Go's build cache.
  4. Go checks GOBIN.
  5. If GOBIN is set, it writes greet there. Otherwise, it writes greet to $GOPATH/bin.
  6. If that destination directory is on PATH, you can run the command from anywhere:
greet

On Windows, the installed file is normally named greet.exe.

Real World Use Cases

  • Installing development tools: Install commands such as linters, code generators, or test helpers into $GOPATH/bin or GOBIN.

    go install golang.org/x/tools/cmd/goimports@latest
    
  • Installing a command from a repository: Build and install a versioned command without first cloning the repository.

    go install example.com/tools/acmecli@v1.4.0
    
  • Building a release artifact: Put a binary in a release directory with a known name.

    go build -o dist/my_new_toy ./cmd/my_new_toy
    
  • System-wide deployment: A package manager, container image build, CI job, or administrator copies a tested binary to /usr/local/bin or another controlled location.

  • Multiple project commands: A repository can use cmd/api, cmd/worker, and cmd/admin as separate executable entry points.

Take Quiz

Real Codebase Usage

In real Go projects, go install is most commonly used for developer tools, while go build -o is commonly used for application artifacts.

Install a pinned development tool

A tool can be installed at an explicit version:

go install example.com/tools/mockgen@v1.6.0

Using an explicit version makes automation more repeatable than always using @latest.

Build an application for CI or releases

A CI pipeline usually creates an artifact in a project directory:

go build -trimpath -o dist/server ./cmd/server

The pipeline can then test, archive, sign, copy, or package dist/server.

Use a task runner only when repeated commands need coordination

You do not need a Makefile merely to install one Go command. A Makefile can still be useful when a project needs multiple repeatable actions, such as formatting, testing, generating code, building several binaries, and preparing a release.

build:
	go build -o dist/my_new_toy ./cmd/my_new_toy

test:
	go test ./...

The Makefile is optional; it is a convenience layer around commands, not a requirement of Go.

Common Mistakes

Assuming go install uses /usr/local/bin

This is not Go's default behavior. go install uses GOBIN, or $GOPATH/bin when GOBIN is unset.

Avoid the assumption by checking:

go env GOBIN GOPATH

Confusing GOROOT with GOPATH

  • GOROOT is the Go installation and toolchain location.
  • GOPATH is a workspace-related location that, among other things, provides the default bin directory for installed commands.

Do not manually copy your programs into GOROOT/bin; a Go upgrade may replace that directory.

Forgetting to add the install directory to PATH

The command can be installed successfully but still appear to be “not found.”

export PATH="$(go env GOPATH)/bin:$PATH"

If you use GOBIN, add GOBIN instead.

Setting GOBIN to a relative path

This is invalid:

export GOBIN=bin

Use an absolute path:

export GOBIN="$HOME/.local/bin"

Using go build when you intended a reusable installed tool

This command creates an executable in the working directory by default:

go build ./cmd/greet

Use go install ./cmd/greet when you want the command placed in your configured Go binary directory.

Installing directly into a privileged directory during ordinary development

Avoid making normal builds depend on sudo. Build to a local directory first, then use a controlled installation or packaging step when needed.

Comparisons

Command or locationMain purposeTypical output locationBest use
go build ./cmd/appCompile a commandCurrent directory by defaultQuick local builds
go build -o dist/app ./cmd/appCompile to an exact pathPath passed to -oCI, releases, deployment artifacts
go install ./cmd/appCompile and install a local commandGOBIN or $GOPATH/binCommands you want on your PATH
go install module/path@versionInstall a versioned external commandGOBIN or $GOPATH/binDeveloper tools and CLIs
go run ./cmd/appCompile and run without keeping a named executableTemporary build outputTrying a program quickly

go build is about producing a build result. go install is about placing a command in Go's configured command directory. go run is about immediately executing code.

Take Quiz

Cheat Sheet

# Show Go directories
go env GOROOT GOPATH GOBIN

# Build a command; output is normally in the current directory
go build ./cmd/app

# Build to a specific file
go build -o dist/app ./cmd/app

# Install a local command to GOBIN or GOPATH/bin
go install ./cmd/app

# Install a versioned command from a module
go install example.com/tool/cmd/tool@v1.2.3

# Configure a custom installation directory (must be absolute)
export GOBIN="$HOME/.local/bin"
go install ./cmd/app

# Make installed commands discoverable
export PATH="$HOME/.local/bin:$PATH"

Rules to remember:

  • GOBIN takes priority over $GOPATH/bin.
  • If GOBIN is empty, commands go to $GOPATH/bin.
  • GOROOT is for the Go toolchain, not normally for your applications.
  • Use go build -o when an application must be written to an exact destination.

FAQ

What is the difference between go build and go install?

go build compiles code and produces an executable in the current directory by default for command packages. go install compiles and places command executables in GOBIN or $GOPATH/bin.

Where does go install put binaries?

It uses GOBIN if that environment variable is set. Otherwise, it uses $GOPATH/bin.

Does go install install programs into GOROOT/bin?

Normally, no. GOROOT/bin belongs to the Go toolchain. Check your actual configuration with go env GOROOT GOPATH GOBIN.

How do I change the go install destination?

Set GOBIN to an absolute directory, such as export GOBIN="$HOME/.local/bin".

Can I make Go install directly to /usr/local/bin?

You can set GOBIN=/usr/local/bin if you have permission, but this is often not ideal for ordinary development. Alternatively, use go build -o /usr/local/bin/app, usually through a controlled deployment step.

Do I need a Makefile to install a Go program?

No. go install and go build -o cover common cases. Use a Makefile or another task runner only when you want convenient, repeatable project commands.

Why is an installed Go command not found in my shell?

Its destination directory is probably not on your PATH. Add GOBIN or $GOPATH/bin to PATH.

Should I use @latest with go install?

@latest is convenient for interactive use. For reproducible scripts and team tooling, prefer a specific version such as @v1.2.3.

Take Quiz

Mini Project

Description

Create a small Go command-line program and practice both building a release artifact at a chosen path and installing the command into Go's configured binary directory. This reflects the common distinction between shipping an application and installing a developer tool.

Goal

Build and install a greet command, then verify where each command places its executable.

Requirements

Create a Go command named greet that prints a greeting.

Take Quiz

Keep learning

Related questions

View more