Application code
Let’s start by creating a program we can run. In Go, there is a convention of placing these in acmd folder. Let’s create cmd/hello/main.go with this basic content:
Running the go tool
To ensure we’re using the Bazel-managed version of the Go SDK rather than something you might happen to have installed on your computer, we replace go commands with the executable @rules_go//go target that comes from rules_go. To make this even easier to discover, our repository has this aliased at ./tools/go. Under the covers, you can see that script is just running the rules_go target, and then ensuring the correct working directory.
If you prefer, you could alias the go command in your terminal to run this script instead, so you don’t need to remember to run the correct one.
External dependencies
As you can see, our application uses thecowsay third-party library. We’ll need to add this to our go.mod file like we would in any Go project. We could use the go get command, but this installs the library to a system location which differs from how Bazel manages dependencies. So instead we’ll use the mod tidy command:
go.mod file, which is how Go provides for reproducible builds. If you open that file, you should see this line was added for you. (The version may differ of course, since our Go source file didn’t specify any constraint).
v1.0.2 and point it to malicious code. The go.sum file provides the cryptographic hash of the library at the time we ran go mod tidy, following the “Trust on First Use” principle.
Additionally, rules_go exposes an external repository where this library is built from sources. Thanks to the strict visibility feature of bzlmod, this dependency must be declared in MODULE.bazel. Looking in that file, you’ll see this line was also added for you:
If you used earlier versions of Go with Bazel, you will notice this is significantly simpler to set up!
Now that the
go.mod file is read directly, you no longer need go_repository rules.Generate BUILD files
Next we need ago_binary target to make our application runnable. As we learned in the 101 course, we can use the gazelle command:
cmd/hello/BUILD.bazel file. You’ll see something like the following has been automatically added for you:
Aspect CLI provides the
configure command.
If you are in a project using vanilla Bazel, you’ll have to follow the gazelle setup instructions, and build the Gazelle binary from source on each developer’s machine.Run the application
Thebazel run command can be used with a label as a shorthand for “build the application and then spawn the resulting binary”. So we can now run:

