nao1215/gup: managing the Go binaries that go install leaves behind
Fast manager for Go-installed binaries in $GOBIN: update, export/import, and migrate toolsets across machines
At a glance
- What is it?
- gup treats $GOBIN as a managed toolset rather than an append-only directory, adding parallel updates, version pinning, export/import and migration on top of go install. The trade-off is that it shells out to the go command, so it inherits Go's toolchain constraints.
- Who is it for?
- Adopt gup if you install Go command-line tools with go install on more than one machine and want the set reproducible, or if you need to hold a tool at a fixed version. Skip it if your tools come from a system package manager, since gup only manages what lives in $GOBIN, and skip it if you cannot install the Go toolchain, because the README states the gup command uses the go command internally.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap gup fills in the Go tool workflow
The README states the problem plainly: go install places each program in $GOBIN ($GOPATH/bin) but never updates it again, keeps no manifest of what it installed, and offers no way to hold a tool at a version you depend on. That is accurate. A developer who installs a dozen linters, generators and small utilities over a year ends up with a directory of binaries whose provenance is only recoverable by guessing module paths from file names. Keeping them current means remembering each module path and re-running go install by hand.
gup is aimed at that person: someone who treats $GOBIN as a working toolset rather than a dumping ground, and who wants the same set on a laptop and a desktop. It is not a general package manager. It manages binaries that are already there, plus the operations around them: list and check what is installed, remove binaries, export and import the set to reproduce it elsewhere, and migrate it to a new $GOBIN. The README also lists pinning selected tools to exact versions, which is the operation go install has no answer for at all.
What gup does when you run gup update
The mechanism is a wrapper around the go command rather than a reimplementation of module resolution. The README says the gup command uses the go command internally, so the golang installation is required. That single sentence sets most of the design constraints: gup reads the binaries under $GOBIN, works out which module each came from, and shells out to Go to rebuild them.
The README's own example shows the output shape. Running gup update subaru gup ubume produces lines like [1/3] github.com/nao1215/gup (v0.7.0 to v0.7.1, go1.20.1 to go1.22.4) and [2/3] github.com/nao1215/subaru (Already up-to-date: v1.0.2 / go1.22.4). Two things are visible in that format. Updates run with a counter, and gup reports both the module version and the Go toolchain version that built each binary. Reporting the toolchain version matters because a tool rebuilt with a newer Go is a different artifact even when its own version has not moved.
The README states that gup update updates every binary under $GOBIN in parallel. Parallelism is the reason a full refresh stays tolerable when the toolset grows, though it also means several go processes may be competing for the module cache and network at once. The README does not document a concurrency limit or a flag to serialize updates.
Installing gup and updating your first tools
The README lists many install paths: homebrew-core, the winget community repository, the mise and aqua registries, nixpkgs, the AUR, prebuilt .deb/.rpm/.apk packages and archives on the release page, and go install. If you already have a Go toolchain, go install is the shortest route. Building from source needs Go 1.25 or newer, and go.mod declares Go 1.25 as the minimum.
go install github.com/nao1215/gup@latestAfter that, gup itself lives in $GOBIN alongside the tools it manages, which is why it can update itself as part of a full run. Confirm the install with either the version subcommand or the top-level flag; the README shows both forms.
gup --version
gup versionTo see what gup considers part of your toolset, and then to bring everything current, the README's usage section gives these operations. The update output prints one line per binary with the old and new module version and the Go version that built it, or Already up-to-date when nothing changed.
gup list
gup updateOn macOS, note the constraint the README spells out: the prebuilt release binaries are built with the latest Go 1.27 patch release, and because Go 1.27 dropped support for macOS 12 and earlier, those binaries require macOS 13 Ventura or newer. On an older macOS, the README's advice is to build from source with a Go version that still supports it. On Linux and Windows the release archives and packages are the fastest route if you would rather not install Go at all, but remember that gup still needs the go command at runtime.
The go command dependency is the real boundary
Every management feature gup advertises sits on top of a working Go installation. The README says this in the packaging section without softening it: gup command uses the go command internally, so the golang installation is required. A prebuilt .deb or a winget package removes the need to build gup, but it does not remove the need for Go itself. Anyone who wants a standalone updater for Go binaries, on a machine where the Go toolchain is absent or deliberately kept out of PATH, is looking at the wrong tool.
There are two further limits worth naming. The first is scope: gup manages binaries under $GOBIN and nothing else. Tools installed through a distribution package manager, a language-specific installer, or a container image are outside its view, and the README does not present it as a replacement for those. The second is that the README does not document rollback. If an update leaves a tool broken, the documented operations are pinning, removing, and reinstalling; there is no described command that restores the previous binary from a backup. Treat a full gup update as a forward-only operation and pin the tools whose breakage would cost you an afternoon.
Network dependence is implied rather than stated. Because updates go through the go command, a machine without access to the module proxy or its cache cannot update anything, and the README does not describe an offline mode.
How gup differs from a dotfiles manager or a version manager
The nearest habit gup replaces is a hand-written list of go install commands in a dotfiles repository. That approach records module paths but not versions, and replaying the list is sequential and manual. gup's export and import commands exist for exactly this case: export the current set, commit the file, and import it on another machine. The README describes export and import as reproducing the set, which is a stronger guarantee than a shell script because the exported data comes from what is actually installed rather than from what someone remembered to write down.
A second comparison is with version managers such as mise, which the README lists as a distribution channel for gup itself. The approaches differ in what they control. A version manager installs and pins the toolchains and tools it knows about from its own registry; gup operates on whatever is already in $GOBIN, including tools that never appeared in any registry. That makes gup broader in coverage and shallower in guarantees: it can manage a binary from an obscure module path, but it cannot tell you whether that module is trustworthy. For a toolset made of well-known projects, a version manager gives you declarative pinning with less machinery. For a toolset assembled ad hoc over years, gup is the one that can see all of it.
Release integrity, licence and what maintenance costs you
gup is Apache-2.0. That is a permissive licence, and the practical implication for a team is that redistributing or bundling the binary inside an internal image is normally straightforward, provided the licence text and notices travel with it. This is not legal advice; the LICENSE file in the repository is the authoritative text, and organizations with a review process should run it through that process.
On supply chain, the README documents more than most tools of this size. Each release ships checksums.txt signed with cosign in keyless mode, producing checksums.txt.sigstore.json, an SPDX software bill of materials attached to each release archive, and SLSA build provenance attested through GitHub OIDC. The README gives the verification commands, including a cosign verify-blob invocation with the certificate identity regexp pinned to the release workflow and the GitHub Actions OIDC issuer, followed by sha256sum --check --ignore-missing checksums.txt. Build provenance can be checked with gh attestation verify against the repository. If your organization already requires provenance checks for binaries, gup gives you something to check.
The repository is not archived, and the last push was on 2026-09-14. Recent releases are v1.9.0, v1.9.1 and v1.9.2, the last dated 2026-09-12. Upgrade cost is low for the tool itself: gup is a single binary, and if you installed it with go install it can update itself in the same run that updates everything else. The cost that does not go away is the toolchain. Unit tests run on Go 1.25, 1.26 and 1.27 across Linux, macOS and Windows, with a separate job tracking the latest Go release, so gup tracks Go's release cadence closely. A team pinned to an older Go for other reasons should check that its version is still supported before adopting.
Editorial conclusion
Adopt gup if you install Go command-line tools with go install on more than one machine and want the set reproducible, or if you need to hold a tool at a fixed version. Skip it if your tools come from a system package manager, since gup only manages what lives in $GOBIN, and skip it if you cannot install the Go toolchain, because the README states the gup command uses the go command internally. Before relying on it, run gup list on a machine where you know the contents of $GOBIN and confirm every binary you care about appears, then check the release page for a package matching your distribution and architecture.
Frequently asked questions
Does gup need Go installed if I use the prebuilt package?
Yes. The README states that the gup command uses the go command internally, so the golang installation is required, even when you install gup from a .deb, .rpm, .apk or winget package. Prebuilt packages only remove the need to build gup itself.
Which operating systems does gup support?
The README lists Linux, macOS and Windows, with unit tests running on all three. The prebuilt macOS binaries require macOS 13 Ventura or newer because they are built with Go 1.27, which dropped support for macOS 12 and earlier.
Can gup hold a Go tool at a specific version?
The README states that gup can pin selected tools to exact versions. That is the operation go install lacks, and it is the documented way to protect a tool you depend on from a full gup update.
What Go version do I need to build gup from source?
go.mod declares Go 1.25 as the minimum, and the README says building from source needs Go 1.25 or newer. On an older Go, the README suggests installing a prebuilt release binary or a package instead.
Can I reproduce my Go toolset on another machine with gup?
The README lists export and import commands that move the set of installed tools to another machine, and a migrate command for moving the set to a new $GOBIN. The exported data reflects what is actually installed rather than a hand-maintained list.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nao1215-gup)