Self-hosted service
pulumi/kubespy avatar
pulumi/kubespy

kubespy: the readme says Go 1.19 is enough and the module file requires 1.26

Tools for observing Kubernetes resources in real time, powered by Pulumi.

3,085 stars93 forksGoApache-2.0

At a glance

What is it?
A small observation tool that watches a Kubernetes resource and reports how it changes, derived from work done on a cloud provider's command line tool. It has four commands, two of which differ only in how they format the same data, and its documentation and its build metadata disagree about the toolchain and about which version of the code you actually get.
Who is it for?
Adopt this when you are debugging why a workload is not settling, since watching a resource's status diff as it happens answers questions that a describe call does not. Three things to know.
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 1 day 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • pulumi/kubespy3,085 ★ · +2
Star history
Repository2026-09-242026-11-14
pulumi/kubespy3.1k3.1k

2 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The readme's Go floor is seven minor versions below what the module requires

The source install section states its prerequisite as Go version one point nineteen or later, and the command it gives is:

sh
go install github.com/pulumi/kubespy@latest

The module file, in the same repository, declares its language requirement as one point twenty six point six. So the two files disagree about the minimum toolchain by seven minor releases, and the one a newcomer reads first is the permissive one. This is the kind of drift that happens when a project keeps raising its floor as the ecosystem moves and the installation section is not revisited, and it has a practical consequence beyond confusion: the command above will simply fail on the older toolchain the readme promises is enough. Anyone hitting that error should trust the module file.

Three of the four install routes resolve to a build from 2024

There are four ways to install this and only one of them tracks the current code. The Homebrew route goes through a package manager whose formula may be updated independently. The binary route tells you to get the latest release, which is version zero point six point three from April 2024. The command line plugin route also starts from a release, with the additional step of renaming the binary so the Kubernetes command line tool finds it. And the source route ends in an at-latest suffix, which resolves to the newest tagged version rather than to the tip of the branch. Since the last push to this repository is three days old and the last release is two and a half years old, three documented routes hand you 2024 code and only the package manager route tracks the tree.

The module pins a provider commit from three days ago

Among the direct dependencies there is a provider module whose version is not a release number but a pseudo-version: a date, a timestamp and a commit hash, dated three days before the last push to this repository. So the current source of this tool is only buildable against a dependency that was never tagged, and the version string is unrecognisable to anyone reading a dependency report. The rest of the direct list is more conventional: the colour library for output, the JSON diff library that produces the diffs, the command line framework, and the two Kubernetes client libraries. But that provider entry is where the tool's real coupling lives, and it is why the gap between the last release and the current tree cannot be closed by tagging: the current code expects an untagged provider.

Two of the four commands differ only in how they format the output

The usage section lists four commands and three of them take an API version, a kind and a name. The first emits changes to the status field only. The second emits changes to any field. The fourth emits changes to any field as well, but as a JSON array rather than as a diff. So the second and fourth commands watch the same thing and differ only in serialisation, which is not stated in the list and is only discoverable by reading both descriptions. The third command is the odd one out in a different way: it takes no API version, because it aggregates the changes a higher level resource makes into a summary rather than watching one object, which is the reason it exists.

A bare make runs a tidy and rewrites your lock file

The build file is fifteen lines with five targets and no default goal, which means the first target is what a bare invocation runs. That first target is not a build. It is the one that runs the module tidy command:

code
ensure::
	go mod tidy

So typing make in a clean checkout silently rewrites the dependency files, which is the opposite of what a target called ensure usually implies and the opposite of what a first target in a build file implies. The actual build and install targets are there alongside it, and the test target runs with verbose output, coverage, a one hour timeout and a parallelism of ten. None of that is wrong; the surprise is entirely in the ordering.

Every target uses the double-colon form

All five targets are written with two colons rather than one. That form is legal and occasionally useful, but it is not the ordinary spelling, and it behaves differently in ways that are easy to miss. Each double-colon rule is independent, so two rules producing the same target do not merge their prerequisites and recipes the way single-colon rules do; there are no warnings either way. Nobody has apparently hit a problem here, which is the probable reason it survived. It is the kind of detail that makes a small build file look like it was copied from somewhere else, and a reader who assumes it is an ordinary single-colon file will mispredict what a second invocation does.

The live display comes from a dependency pinned to 2017

The tool's defining behaviour is that its output updates in place while you watch, rather than scrolling past you. That behaviour comes from one of the direct dependencies, and its version string is a pseudo-version dated 2017. So a tool whose release history runs to 2024 and whose source is being changed in 2026 depends on a nine-year-old revision of a live-output library, pinned to a commit rather than to a tag. There is a reasonable case for pinning an old revision of a display library that does one small job, and the pin at least makes the build reproducible. It is worth knowing when you upgrade anything else, because that entry is the one most prone to break, and it is the one a tidy will not move for you.

The roadmap is tracked twice, in the feature list and in a separate file

The features section of the README is written as a task list with two items done and two undone. The done items are that any resource the API server knows about is supported, custom resources included, achieved by using the discovery client so anything queryable is reachable, and that changes are displayed live. The undone items are case-insensitive aliases, so that a lowercase kind works as well as the canonical capitalisation, and status updates matched by pattern rather than by exact name. That second one is the item that matters most in practice, because controllers routinely create objects with generated names, and watching one means knowing the name it chose. The tree also contains a separate roadmap file, so the same two open items are recorded in two places that can drift.

Editorial conclusion

Adopt this when you are debugging why a workload is not settling, since watching a resource's status diff as it happens answers questions that a describe call does not. Three things to know. Three of the four documented install routes resolve to a release from 2024, so check which build you have before you file a bug against current behaviour. The toolchain floor in the readme is wrong by seven minor versions. And the roadmap item you are most likely to want, matching generated resource names, is still unchecked, which matters whenever a controller creates objects with generated names.

Frequently asked questions

What is pulumi/kubespy?

It is a small tool that observes how Kubernetes resources change in real time, derived from work done to make deployments predictable inside a cloud provider's command line interface. Run it against any resource and it watches and reports changes continuously until you stop it.

What are the kubespy commands?

Four. One emits changes to the status field only as a diff, one emits changes to any field as a diff, one emits changes to any field as a JSON array, and one aggregates the changes a higher level resource makes into a live high-level summary. The first, second and fourth take an API version, a kind and an optional namespace and name; the third takes only a kind and name.

How do I install kubespy?

Four documented routes: a Homebrew formula, a release binary you rename and make executable, a rename that lets the Kubernetes command line tool find it as a plugin, and a source install from the module path. Note that the release, plugin and source routes all resolve to the newest tag rather than to the current source.

Which Go version does kubespy need?

The installation section says one point nineteen or later, while the module file declares one point twenty six point six. The module file is the one to trust; the readme figure has fallen behind the actual requirement.

Can kubespy watch custom resources?

Yes. That is the first completed item on the feature list, and it works by using the discovery client to find out what the API server knows about, which is what allows any resource to be queried by kind. The open items are case-insensitive aliases and matching objects by pattern instead of by exact name.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. pulumi/kubespy on GitHub
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pulumi-kubespy.svg)](https://hysenlabs.com/projects/pulumi-kubespy)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/pulumi-kubespy.svg)](https://hysenlabs.com/projects/pulumi-kubespy)

Was this useful?