# How to Update All Modules Using Go Mod After Dependency Changes

> Update all Go modules efficiently after dependency changes with go mod tidy. Ensure consistency and reproducibility for your entire project module graph. Learn how now.

- Repository: [Go/go](https://github.com/golang/go)
- Tags: how-to-guide
- Published: 2026-02-21

---

**Run `go mod tidy` after any dependency change to automatically add missing requirements, remove unused ones, and ensure your entire module graph stays consistent and reproducible.**

When you modify dependencies in a Go project—whether through `go get`, `go mod edit`, or manual edits to `go.mod`—the rest of your module graph can drift into an inconsistent state. According to the `golang/go` source code, the canonical way to update all modules and restore consistency is the `go mod tidy` command. This tool scans your entire codebase, reconciles version constraints, and produces a minimal, reproducible build list.

## Why `go mod tidy` Is Essential for Module Consistency

The Go toolchain does **not** automatically propagate dependency changes to the rest of your module graph. When you upgrade one library, transitive dependencies might need version bumps, or old requirements might become obsolete. Without cleanup, your `go.mod` and `go.sum` files accumulate unused entries and version conflicts that break reproducible builds.

**`go mod tidy`** solves this by performing two atomic operations:

- **Adding missing requirements**: It scans every package (including tests) and adds any imported module not already listed in `go.mod`, selecting the minimal version that satisfies the import path.
- **Removing unused requirements**: It drops entries from `go.mod` and `go.sum` that are no longer needed to build the module or its tests.

## How `go mod tidy` Works Under the Hood

The implementation relies on a sophisticated graph-editing algorithm that lives in the Go toolchain source tree.

### Command-Line Interface and Flag Handling

The entry point is implemented in [`src/cmd/go/internal/modcmd/tidy.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modcmd/tidy.go). The `runTidy` function registers flags such as `-e`, `-v`, `-diff`, `-go`, and `-compat` (lines 22–78), then initializes a fresh module loader state. It forces module mode with `ForceUseModules = true` and prepares to load the complete package tree.

### Loading the Complete Package Graph

In [`src/cmd/go/internal/modload/load.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modload/load.go), the command invokes `LoadPackages` with the `Tidy: true` option. This loads **all** packages in the module—including test dependencies—to build a comprehensive graph of requirements. The loader constructs a `ModuleGraph` that represents every direct and transitive dependency with their version constraints.

### Editing Requirements and Resolving Conflicts

The core logic resides in [`src/cmd/go/internal/modload/edit.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modload/edit.go) inside the `editRequirements` function (lines 23–50). This algorithm:

1. Merges the **must-select** set (explicit versions from the command line or `go.mod`) with **try-upgrade** candidates.
2. Determines the pruning mode (pruned vs. unpruned) based on the Go version directive.
3. Constructs a **selectedRoot** map that records the target version for each root module.
4. Repeatedly expands the graph using `extendGraph` and walks it with a **disqualification tracker** (`dqTracker`) to locate version conflicts.
5. Downgrades or upgrades roots until the graph is internally consistent.

After resolution, the edited `Requirements` object is written back to `go.mod`, and `go.sum` is updated with the exact cryptographic hashes needed for reproducible builds.

## Step-by-Step Workflow to Synchronize Dependencies

Use this sequence after updating any dependency to ensure your entire module graph stays synchronized:

```bash

# 1. Upgrade specific dependencies or all dependencies

go get -u ./...                    # Update all direct and indirect dependencies

# OR target a specific version

go get example.com/module@v1.4.2

# 2. Synchronize the entire module graph

go mod tidy                        # Adds missing deps, removes unused ones

# 3. (Optional) Preview changes without applying them

go mod tidy -diff                  # Shows unified diff of go.mod and go.sum

# 4. Verify the changes

git diff go.mod go.sum             # Review before committing

```

Running `go mod tidy` is idempotent and efficient. The command reuses the module cache (`$GOPATH/pkg/mod`) and only contacts the proxy for modules whose sums are missing from `go.sum`.

## Optional Flags for CI and Legacy Compatibility

When automating dependency updates, several flags control `go mod tidy` behavior:

- **`-e`**: Continue processing even if some packages fail to load. Essential for large monorepos where temporary build breaks occur.
- **`-v`**: Verbose output that prints each module added, upgraded, or removed.
- **`-diff`**: Displays a unified diff of changes without modifying `go.mod` or `go.sum`. Ideal for CI checks that enforce manual review.
- **`-go=VERSION`**: Forces the `go` directive in `go.mod` to a specific version, affecting module graph pruning behavior.
- **`-compat=VERSION`**: Ensures the resulting graph remains compatible with older Go toolchains, preventing the use of newer module graph features.

## Summary

- **`go mod tidy`** is the authoritative command to update all modules and ensure consistency after any dependency change.
- The command lives in [`src/cmd/go/internal/modcmd/tidy.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modcmd/tidy.go) and orchestrates the module loader in [`src/cmd/go/internal/modload/load.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modload/load.go).
- The resolution algorithm in [`src/cmd/go/internal/modload/edit.go`](https://github.com/golang/go/blob/main/src/cmd/go/internal/modload/edit.go) handles version conflicts via `editRequirements` and a disqualification tracker.
- Always run `go mod tidy` after `go get` or manual `go.mod` edits to prune unused requirements and add missing transitive dependencies.
- Use `-diff` in CI pipelines to validate dependency changes without applying them, and `-compat` to maintain backward compatibility.

## Frequently Asked Questions

### What's the difference between `go get` and `go mod tidy`?

**`go get`** updates specific dependencies to requested versions but does not clean up the module graph. **`go mod tidy`** synchronizes the entire graph by adding missing requirements and removing unused ones. You should run `go mod tidy` after `go get` to ensure consistency.

### Can I run `go mod tidy` in CI pipelines?

Yes, but use the `-diff` flag for validation checks without modifying files. If you want CI to auto-fix dependencies, run `go mod tidy` followed by `go mod verify` to ensure cryptographic sums match downloaded modules. The `-e` flag helps CI continue even if some packages are temporarily broken.

### Why does `go mod tidy` remove lines from my `go.mod`?

The command removes **unused requirements**—dependencies that no package in your module (including tests) actually imports. This keeps `go.mod` minimal and prevents bloat from old transitive dependencies that are no longer referenced in the code.

### Is it safe to run `go mod tidy` automatically before every build?

Generally yes, but be cautious in multi-module repositories or when working with legacy code. The `-compat` flag ensures you do not accidentally adopt module graph features incompatible with older Go versions. For production builds, commit the resulting `go.mod` and `go.sum` changes to version control rather than running tidy dynamically.