How to Remove or Uninstall a Go Package

Deepak Prasad
Tested on RHEL 10.2 with Go 1.27.0
Package go 1.27.0
Applies to Any host with Go installed; Go 1.24+ for tool directive examples
Privilege Normal user
Scope Remove module dependencies from go.mod, undo go get, drop Go 1.24+ tool dependencies, uninstall go install binaries, and clear the module cache. Does not cover vendor workflows or replacing third-party libraries in depth.
Related guides go.mod file not found
Getting started with Go
Install Go on Ubuntu
Import local package without GOPATH
Golang declared and not used

Go does not ship a universal go uninstall command. What you remove depends on how the package entered your environment: a require line in go.mod, a Go 1.24+ tool directive, a standalone binary from go install, or downloaded source sitting in the module cache. The table below maps each case to the command you actually need.

What you want to remove Recommended action
Project module dependency Remove imports → go get module@nonego mod tidy
Dependency no longer imported go mod tidy may remove it automatically
Go 1.24+ tool dependency go get -tool package@nonego mod tidy
CLI installed with go install package@version Delete the installed executable
Downloaded modules from local cache go clean -modcache

The rest of this guide walks through each row with real commands. Run module commands from the directory that contains go.mod.


Remove a dependency from go.mod

A module dependency is a require line (and its transitive graph) in go.mod. Removing it means changing that graph, not deleting folders by hand. I use a small demo module example.com/remove-demo that previously ran go get github.com/gin-gonic/gin@v1.10.0.

Check why the module is required

List every module in the selected graph so you can see whether the one you care about is still present:

bash
go list -m all

Sample output (trimmed):

output
example.com/remove-demo
github.com/bytedance/sonic v1.11.6
github.com/bytedance/sonic/loader v0.1.1
github.com/cloudwego/base64x v0.1.4
github.com/cloudwego/iasm v0.2.0
...

When the list is long, scroll or filter locally; the important part is confirming the module path and version you plan to drop.

Ask Go why a module is still selected. Use -m so the argument is treated as a module path, not a package path inside that module:

bash
go mod why -m github.com/gin-gonic/gin

With github.com/gin-gonic/gin imported in main.go, the chain names your module and the dependency:

output
# github.com/gin-gonic/gin
example.com/remove-demo
github.com/gin-gonic/gin

If nothing in your code or tests imports the module, you may instead see (main module does not need module github.com/gin-gonic/gin).

Remove direct imports first

If your source still imports a package from the module, deleting the require line alone does not make the dependency unnecessary. Remove or refactor those imports first. For the demo I replace main.go with a stub that no longer references Gin:

bash
printf 'package main\n\nfunc main() {}\n' > main.go

That edit is what tells the module graph the Gin API is no longer used.

Remove it with go get module@none

Request removal of that module from the selected graph:

bash
go get github.com/gin-gonic/gin@none

@none requests removal of that module dependency. Go may also downgrade or remove other modules as needed to maintain a valid module graph. On success it reports what it dropped:

output
go: removed github.com/gin-gonic/gin v1.10.0

Removing one module can downgrade or remove others that depended on it. Do not assume only a single require line changes.

Run go mod tidy

Tidy prunes unused requirements and refreshes go.sum:

bash
go mod tidy

go mod tidy exits silently on success when nothing else needs cleanup. Confirm Gin and its former transitive modules are gone:

bash
go list -m all

Sample output:

output
example.com/remove-demo

Only the main module remains, which matches a project that no longer pulls Gin into the graph.


When go mod tidy is enough

Readers often ask why they cannot delete the import and run go mod tidy alone. That works when the dependency is no longer required by any package or test in your module. After you remove imports, tidy analyzes the module and drops requirements that nothing references.

Use go get module@none when you intentionally want to remove a specific module and are prepared for Go to adjust other dependencies that require it. If removing imports already made the dependency unnecessary, go mod tidy alone is usually sufficient.

go.mod is plain text and you can edit it by hand, but the go commands understand version constraints and the full graph. Prefer go get and go mod tidy so indirect dependencies and go.sum stay consistent.


Remove a Go tool dependency from go.mod (Go 1.24+)

Go 1.24 added tool directives for development tools tracked in go.mod. Add one with:

bash
go get -tool golang.org/x/tools/cmd/stringer@v0.49.0

Go adds a tool line and related require entries. A minimal go.mod can look like this:

text
module example.com/remove-demo

go 1.27.0

tool golang.org/x/tools/cmd/stringer

require golang.org/x/tools v0.49.0

That is different from go install golang.org/x/tools/cmd/stringer@v0.49.0, which places a binary on disk but does not add a tool line to your project's go.mod.

Remove the tracked tool with:

bash
go get -tool golang.org/x/tools/cmd/stringer@none

The tool line disappears from go.mod, but module requirements that were needed by the tool can remain until you run go mod tidy.

Run tidy to remove requirements that are no longer needed:

bash
go mod tidy

After tidy, go.mod typically contains only the module and go lines when no other dependencies remain. You run tools in the module with go tool stringer, not by assuming a global install path.


Uninstall a command installed with go install

go install example.com/cmd/tool@v1.2.3 builds an executable. It does not add a project dependency to the current go.mod when you use a version suffix. The binary lands in GOBIN when that variable is set explicitly; otherwise Go uses the bin directory under the first GOPATH entry (normally $HOME/go/bin).

On a default setup, GOBIN is often empty. Check it first:

bash
go env GOBIN

Sample output on a typical user account (blank line means unset):

When GOBIN is empty, ask where Go keeps module downloads and installed tools:

bash
go env GOPATH

Sample output:

output
/home/user/go

With no GOBIN, go install places stringer at /home/user/go/bin/stringer. If GOBIN is set, delete from that directory instead.

Install a tool to see the default path when GOBIN is unset:

bash
go install golang.org/x/tools/cmd/stringer@v0.49.0

go install finishes quietly; list the binary under GOPATH/bin:

bash
ls -l "$(go env GOPATH)/bin/stringer"

Sample output:

output
-rwxr-xr-x 1 user user 8557462 Aug 23 13:24 /home/user/go/bin/stringer

Deleting that file is the uninstall step. Resolve the install directory before rm, because $(go env GOBIN) alone is unsafe when GOBIN is empty (the path collapses to /stringer):

bash
GOBIN=$(go env GOBIN)
if [ -z "$GOBIN" ]; then
  GOBIN="$(go env GOPATH)/bin"
fi
rm -f "$GOBIN/stringer"

rm -f avoids an interactive prompt in non-interactive shells. Using the same $GOBIN value from above, confirm the binary is gone:

bash
test ! -e "$GOBIN/stringer" && echo "stringer removed"

Sample output:

output
stringer removed

Go has no go uninstall subcommand for these installs.


Why the dependency returns after you remove it

A module can reappear after go mod tidy when something in your module still needs it. Common causes:

  • Another dependency still requires it (indirect requirement).
  • Source or test code still imports it.
  • Generated code imports it.
  • A tool directive still references a package from that module.
  • Tidy restored it because the graph still requires it for a successful build.

Run the diagnostic again with the module path:

bash
go mod why -m github.com/gin-gonic/gin

The printed chain shows which import path pulled the module back in. For a wider view of edges between modules, go mod graph lists requirement pairs; use it when go mod why points at a long indirect chain.

If a parent library is the only reason the module exists, you must remove or replace that parent, or accept the indirect requirement.


Module cache is not package installation

go clean -modcache deletes downloaded module source from the cache (under $GOPATH/pkg/mod by default). It does not:

  • remove require lines from go.mod;
  • delete go install binaries;
  • permanently uninstall dependencies from your project.

The next go build or go test can download modules again. Use cache cleanup to reclaim disk space, not to drop a dependency from a project.


Common mistakes

Mistake Correct approach
Searching for go uninstall Decide whether it is a module, tool dependency, or installed binary
Deleting cache to remove a dependency Change the module graph with imports, go get @none, or tidy
Using go get to uninstall a standalone binary Delete the executable from GOBIN or GOPATH/bin
Ignoring empty $GOBIN When unset, binaries live in $(go env GOPATH)/bin, not /stringer from $(go env GOBIN)/tool
Forgetting go mod tidy after go get -tool @none Tidy removes require lines that only served the tool
Removing a module still imported by code Remove or refactor imports first
Using go mod why with a module without -m Prefer go mod why -m module/path
Assuming @none only changes one line Graph updates may downgrade or remove other modules

References


Summary

Removing a Go package starts with identifying what was added. Module dependencies live in go.mod and leave through import cleanup, go get module@none, and go mod tidy. When you only removed imports and nothing else references the module, go mod tidy alone is often enough.

Go 1.24+ adds a separate case: tool directives tracked with go get -tool, removed with go get -tool package@none and go mod tidy so leftover require lines drop with the tool.

CLI tools from go install package@version are plain files on disk. When GOBIN is empty, they live under GOPATH/bin; when set, under GOBIN. Resolve that path before rm, not $(go env GOBIN)/tool alone. The module cache is yet another layer: go clean -modcache clears downloads but does not edit go.mod.

When a dependency comes back, go mod why -m shows which import path still requires it. Treat that output as the map before you fight tidy or hand-edit go.mod.


Frequently Asked Questions

1. How do I undo go get?

Remove any imports that use the package, then run go get module@none from your module root and go mod tidy. That drops the module from the selected dependency graph when nothing in your module still needs it.

2. Does Go have a go uninstall command?

No. Module dependencies are removed with go get module@none and go mod tidy; Go 1.24+ tool lines use go get -tool package@none followed by go mod tidy; CLI binaries installed with go install are deleted from GOBIN when set or from GOPATH/bin when GOBIN is empty; cached downloads are cleared with go clean -modcache.

3. What is the difference between go get module@none and go mod tidy?

go get module@none explicitly requests removal of a specific module and Go may adjust other dependencies that require it. go mod tidy removes requirements that are no longer needed after your imports and tests are analyzed, and it updates go.sum. When removing imports already made the dependency unnecessary, tidy alone is usually sufficient.

4. How do I remove a tool from go.mod in Go 1.24 or later?

Run go get -tool package/path@none from the module root, then go mod tidy. The first command removes the tool directive; tidy drops module requirements that were needed only for that tool. This is separate from deleting a binary you installed with go install outside the module graph.

5. How do I uninstall a CLI installed using go install?

Run go env GOBIN. When GOBIN is set, delete the executable from that directory. When GOBIN is empty, Go installs to GOPATH/bin (normally /home/user/go/bin). Delete the file there. Go does not provide a dedicated uninstall subcommand.

6. Does go clean -modcache uninstall a package?

No. It deletes downloaded module source from the local cache. Requirements in go.mod stay until you change the module graph, and go install binaries are untouched. The next build can download modules again.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms.

  • Go (programming language)
  • Python (programming language)
  • Java (programming language)
  • MongoDB
  • Kubernetes