Go's dependency system is small and strict, which is exactly why it's worth understanding rather than copying commands blindly. Two files run the whole show — go.mod and go.sum — and once you know what each one does, upgrades, pinning, and vendoring stop being mysterious. This guide covers all of that, then connects it to how Go actually runs on Falix.
| At a glance | |
|---|---|
| You need | A Falix server running the Go application; Go on your own computer helps |
| Plan | Any — on free it runs while your session timer has time left, premium runs 24/7 |
| Time | Twenty minutes |
| New to the Go app? | Go on Falix |
The two files
go.mod is your project's manifest. It's created by go mod init example.com/myapp and describes your module and what it needs:
module example.com/myapp
go 1.22
require (
github.com/go-chi/chi/v5 v5.0.12
golang.org/x/text v0.14.0 // indirect
)
- The
moduleline is your module path (often a repo URL — it doesn't have to be public). - The
goline is the language version your code targets. requirelists dependencies with exact versions. An// indirectcomment means it's a dependency of a dependency, not something you imported directly.
go.sum is the integrity lock. For every module version in your build, it records a cryptographic checksum. When Go downloads a module, it verifies the download against go.sum — so nobody can swap the code under a version you already trusted. You don't edit it by hand; Go maintains it.
🎯 Good to know: Commit both files.
go.moddecides which versions you get;go.sumguarantees you get the same bytes every time. A repo withoutgo.sumbuilds, but you've thrown away the reproducibility Go handed you for free.
Adding and upgrading
Go picks versions using semantic versioning (vMAJOR.MINOR.PATCH) and, by default, the minimum version that satisfies everything — predictable, not "latest wins".
| Command | What it does |
|---|---|
go get github.com/pkg/errors |
Add a dependency (latest release) and record it |
go get github.com/pkg/[email protected] |
Pin an exact version |
go get -u ./... |
Upgrade dependencies to newer minor/patch releases |
go get -u=patch ./... |
Upgrade to newer patch releases only (safest) |
go mod tidy |
Add anything imported but missing, remove anything no longer used, and sync go.sum |
Run go mod tidy before you commit — it's the housekeeping step that keeps go.mod and go.sum honest about what your code actually imports.
⚠️ Heads up: A new major version (v2 and up) is a different module path in Go. Upgrading
chi/v5to a hypothetical v6 means importinggithub.com/go-chi/chi/v6in your code, not just bumping a number. This is "semantic import versioning", and it's why you'll see/v5in import paths.
Vendoring
go mod vendor copies every dependency's source into a vendor/ folder in your repo. With vendor/ present, Go builds from it instead of downloading anything.
- Vendor when you want fully reproducible, network-free builds, or you need your dependencies committed alongside your code (audits, air-gapped builds, or a build step that can't reach the internet).
- Skip it when you're happy for the build to fetch modules — the module cache and
go.sumalready give you reproducibility for most projects.
On Falix, vendoring has one concrete benefit: a Git build step that runs go build will use the committed vendor/ folder and won't need to reach out to the module proxy at all.
Private modules
Public modules just work. Private ones need Go to authenticate to your host, which it can't do with credentials it doesn't have. Two honest options:
- Set
GOPRIVATE=example.com/yourorg/*so Go skips the public proxy and checksum database for those paths — then provide git credentials in the environment where the build runs. - Or vendor the private code so it's already in the repo and no authenticated fetch is needed at build time. On Falix this is usually the simplest path.
The Falix layer
Two facts from Go on Falix shape how all of this plays out here:
- The Go application runs a prebuilt binary — nothing compiles on start. So
go.modchanges don't take effect until you rebuild theappbinary (build locally and upload, or rungo build -o appas a Git post-deploy command). - The Go server has a Packages page. Open Packages from your server menu, search for a module, and press Install — it runs
go get, updates yourgo.modandgo.sumfor you, and shows the job under Tasks. It's the easy way to add or upgrade a dependency without editing files by hand.
⚠️ Heads up: Because Go is compiled ahead of time, installing a package through the Packages page changes
go.modbut not your running binary. Always rebuild (go build -o app) after a dependency change so the new module is actually baked intoapp.
Everything past the Falix-shaped parts is standard Go — the official Go Modules Reference is the complete source of truth for the resolver, replace directives, and the proxy protocol.