xx
.md

Go Package

The Go package provisions a specific official Go SDK and exposes it as a dependency. A global Go installation is not needed when xx runs the build.

Load it with an exact Go release version, without the go prefix:

load("@go@1.26.5", "go", "go_binary", "go_install", "go_run")

Stable versions such as 1.26.0 and 1.26.5, plus official beta and rc versions, use the corresponding release from go.dev. A version absent from official Go metadata fails instead of silently selecting another version.

go

go is a dependency that provisions and activates the selected SDK. Use it with run when calling Go commands directly:

load("@go@1.26.5", "go")
load("@os@1", "run")

run(("go", "test", "./..."), deps=[go])

Activation puts the managed SDK's binary directory and a command-scoped temporary GOBIN first in PATH, then configures isolated Go storage below xx's Go cache. The temporary directory is shared by entrypoints in one xx run command and removed after every task finishes. This prevents tools from remaining available after their install declaration is removed.

VariableBehavior
PATHManaged SDK bin, then temporary GOBIN, then existing entries
GOBINCommand-scoped temporary application directory
GOROOTManaged SDK directory
GOCACHEShared managed build cache
GOMODCACHEShared managed module cache
GOPATHShared managed workspace
GOTOOLCHAINlocal, preventing Go from switching toolchains
GOENVoff, preventing a user Go environment file from changing the build

Other task dependencies can add or override environment values in their declared order. go_binary, go_install, and go_run always restore their managed GOROOT, GOTOOLCHAIN, and GOENV immediately before invoking Go. go_install also restores its isolated GOBIN.

go_run

Run a Go command at a required version without installing it first:

load("@go@1.26.5", "go_run")

go_run(
    package="codeberg.org/tsukinoko-kun/doctopus",
    version="latest",
    args=["build"],
)

go_run invokes go run <package>@<version> <args...> with the selected managed SDK. Package and version follow the same rules as go_install and must be non-empty strings.

ArgumentRequiredDescription
packageYesGo package path without an @version suffix
versionYesVersion query appended to the package path
argsNoString arguments passed to the Go command
depsNoDependencies activated before running the command, in list order

The selected Go SDK is an implicit dependency. go_run returns a dependency and also registers the command as a root task, matching go_install and go_binary behavior.

go_install

Install a Go command at a required version:

load("@go@1.26.5", "go_install")
load("@os@1", "run")

doctopus = go_install(
    package="codeberg.org/tsukinoko-kun/doctopus",
    version="latest",
)
run(("doctopus", "build"), deps=[doctopus])

go_install invokes go install <package>@<version> with the selected managed SDK. It accepts Go version queries such as latest, branch names such as main, semantic versions, and revisions without restricting their format. Both package and version must be non-empty strings.

ArgumentRequiredDescription
packageYesGo package path without an @version suffix
versionYesVersion query appended to the package path
depsNoDependencies activated before installation, in list order

The selected Go SDK is an implicit installation dependency. Each SDK and package version uses a dedicated directory below the temporary GOBIN, preventing concurrent installs from replacing each other's commands. The returned dependency adds that directory to PATH after the managed SDK, so installed commands are available to tasks that depend on it without shadowing go. All installed commands are deleted when the xx run command finishes and must be declared again in later runs. Declaring the same SDK, package, and version more than once in one run is rejected as an output conflict.

go_binary

Build a Go command from one source file or one package directory:

go_binary(
    entry_point="cmd/server",
    deps=[],
    output="bin/server",
    flags=["-trimpath"],
)

Arguments

ArgumentRequiredDescription
entry_pointYesProject-relative Go source file or package directory passed to go build
depsNoDependencies activated before the build, in list order
outputNoProject-relative output file
flagsNoString arguments inserted after go build and before xx's output and entrypoint arguments

The selected Go SDK is always an implicit dependency. Do not add go to deps for go_binary.

Default Output

When output is omitted, xx writes to .xx/out/<name>:

A custom output is used exactly as written, including its extension. xx creates missing parent directories.

Use the output argument instead of passing -o, --o, -o=..., or --o=... in flags. Those forms are rejected so xx can validate and reserve the output safely.

Paths and Conflicts

Entrypoints and outputs must stay inside the project, including after symlinks are resolved. An output cannot replace its entrypoint, point to an existing directory, or overlap another active build output. These checks prevent concurrently running tasks from writing the same path.

SDK Download and Cache

On first use, xx reads official Go release metadata, downloads the portable archive for the host, verifies its exact size and SHA-256 checksum, validates the extracted SDK, and publishes it into the operating-system user cache under xx/go/<version>.

Later builds reuse a valid cached SDK. Concurrent tasks requesting the same version share setup work. An invalid cached SDK is removed and provisioned again.

Supported SDK hosts:

Unsupported hosts, missing official archives, and checksum mismatches fail with an error.

Examples

See Go examples for complete build files covering binaries, package directories, flags, environment dependencies, and direct Go commands.