go mod download vs go mod tidy: Key Differences and When to Use Each
The primary difference is that go mod download populates the local module cache without modifying module definitions, while go mod tidy cleans up go.mod and go.sum by adding missing dependencies and removing unused ones.
Both commands operate on a module’s dependency graph, but they serve distinct purposes within the Go toolchain. According to the golang/go source code, understanding the architectural separation between cache management and dependency graph maintenance is essential for efficient CI pipelines and reproducible builds.
Core Functional Differences
go mod download focuses exclusively on fetching and verifying module contents. It parses the existing go.mod file to identify required modules, then ensures their source code is present in the local module cache ($GOMODCACHE). The command never adds or removes require statements from go.mod, though it will append checksum entries to go.sum for any newly downloaded modules.
go mod tidy performs dependency graph maintenance. It scans the source tree to discover imported packages, computes the minimal set of required modules, and reconciles that set with the current go.mod. This process may add new require statements, drop unused ones, and prune irrelevant exclude or replace directives. Finally, it regenerates go.sum to contain checksums exactly for the modules required by the final go.mod, removing any stale entries.
How go mod download Works
The implementation resides in [src/cmd/go/internal/modcmd/download.go](https://github.com/golang/go/blob/master/src/cmd/go/internal/modcmd/download.go). When executed, the command follows this flow:
- Parse Requirements: Reads the current
go.modto obtain the list of required modules. - Fetch Modules: Invokes
modfetch.DownloadModule(defined insrc/cmd/go/internal/modfetch/fetch.go) for each module entry. - Cache Population: Resolves the module version, contacts the configured proxy or cache, verifies the checksum against
go.sum, and stores the module zip and source files in$GOMODCACHE. - Output: If
-jsonis supplied, emits aModuleJSONstruct (lines 94–112 indownload.go) describing the download result.
# Pre-populate the cache for all dependencies listed in go.mod
go mod download
# Download a specific version with machine-readable output
go mod download -json golang.org/x/tools@latest
How go mod tidy Works
The logic lives in [src/cmd/go/internal/modcmd/tidy.go](https://github.com/golang/go/blob/master/src/cmd/go/internal/modcmd/tidy.go). This command orchestrates the tidy algorithm from the modload package:
- Load Graph: Calls
modload.LoadAllModulesto initialize the module loading system. - Source Analysis: Walks the source tree to discover all imported packages and computes the minimal required module set.
- Reconcile Dependencies: Compares the computed set against the existing
go.mod, adding missingrequirestatements and removing unused ones. - Write Changes: Invokes
modload.WriteGoModto rewritego.modandmodload.WriteGoSumto generate a cleango.sumcontaining only the necessary checksums.
Unlike go mod download, go mod tidy accepts no arguments and always operates on the module in the current directory.
# Clean up go.mod and go.sum after removing an import
go mod tidy
When to Use Each Command
Use go mod download when you need to:
- Pre-populate the module cache before running tests or CI steps that require dependency source code.
- Verify that a specific module version can be fetched from the proxy.
- Populate
$GOMODCACHEin a Docker layer without modifying build files.
Use go mod tidy when you need to:
- Ensure the module’s dependency list is accurate after adding or removing code imports.
- Keep
go.modandgo.summinimal and reproducible before committing changes. - Prune unused dependencies that are no longer referenced by the codebase.
Summary
go mod downloadonly readsgo.modto fetch modules into$GOMODCACHE, never modifying the module definition itself.go mod tidyactively modifiesgo.modandgo.sumto reflect the actual imports used in the source code.- Download appends to
go.sumbut never deletes entries; tidy regeneratesgo.sumto match the final dependency set exactly. - Download accepts specific module arguments and supports
-jsonoutput; tidy works only on the current directory module.
Frequently Asked Questions
Does go mod download update the go.mod file?
No. According to the implementation in download.go, the command only reads the existing go.mod to determine which modules to fetch. It never adds or removes require statements, though it may append new checksum entries to go.sum for modules that were not previously recorded.
Can go mod tidy be run with specific module arguments?
No. The go mod tidy command takes no arguments and always operates on the module in the current working directory. It scans the entire source tree to determine the complete set of required dependencies before updating the module definition files.
Which command should I run before committing code to version control?
Run go mod tidy. This ensures that go.mod contains the minimal set of required dependencies and that go.sum includes only the checksums for those specific modules. This practice keeps the repository state clean and reproducible for other developers.
How do these commands handle the go.sum file differently?
go mod download writes checksum entries for any downloaded modules that were not already present in go.sum, but it does not delete any entries. In contrast, go mod tidy rewrites go.sum completely so that it contains checksums exactly for the modules required by the final go.mod, removing any unused entries in the process.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →