> ## Documentation Index
> Fetch the complete documentation index at: https://aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Create and run an application

> Create and run a Go application with Bazel, following the cmd folder convention and importing third-party modules to build your first go_binary target.

In this course we will work in a Go Bazel repository. Clone the [Go starter template](https://github.com/aspect-starters/go) to follow along.

## Application code

Let’s start by creating a program we can run. In Go, there is a convention of placing these in a `cmd` folder. Let’s create `cmd/hello/main.go` with this basic content:

```go theme={null}
package main

import (
    "net/http"
    "nmyk.io/cowsay"
)

func main() {
    http.HandleFunc("/", HelloServer)
    http.ListenAndServe(":8080", nil)
}

func HelloServer(w http.ResponseWriter, r *http.Request) {
    cowsay.Cow{}.Write(w, []byte("Hello, world!"), false)
}
```

## 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 the `cowsay` 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:

```bash theme={null}
% ./tools/go mod tidy
```

This results in updating the `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).

```bash theme={null}
require nmyk.io/cowsay v1.0.2
```

For supply-chain security, we might be suspicious that the maintainers of this library could accidentally allow an attacker to re-tag this `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:

```bash theme={null}
use_repo(go_deps, "io_nmyk_cowsay")
```

That’s it! We’ve got this library ready to use as a dependency of our app.

<Note>
  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.
</Note>

## Generate BUILD files

Next we need a `go_binary` target to make our application runnable. As we learned in the 101 course, we can use the `gazelle` command:

```bash theme={null}
% aspect gazelle
```

Now look inside the `cmd/hello/BUILD.bazel` file. You’ll see something like the following has been automatically added for you:

```bash theme={null}
go_library(
    name = "cmd_lib",
    srcs = ["server.go"],
    importpath = "example.com/bazel105/cmd",
    visibility = ["//visibility:private"],
    deps = ["@io_nmyk_cowsay//:go_default_library"],
)

go_binary(
    name = "cmd",
    embed = [":cmd_lib"],
    visibility = ["//visibility:public"],
)
```

<Note>
  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.
</Note>

## Run the application

The `bazel 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:

```bash theme={null}
% bazel run cmd/hello
```

The server starts up, and we can navigate to [http://localhost:8080/](http://localhost:8080/) to see the website it serves.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.