“openapi-changes is a big pile of tangled shit, and I would avoid it for now. It works, but it’s janky-ass software.“
What a quote!
It’s not verbal bashing from a customer or a competitor - it’s my own.
openapi-changes sucks
Hearing someone bash your baby, insult your labor of love, or crush your creativity is never easy. And quite frankly, if we’re honest, it hurts.
“Your work is bad, and you are not worthy.”
It still triggers my impostor syndrome.
However, no one is saying this, it’s my own inner monologue.
No, but mate… it is bad.
Yeah, I know, the code really is bad.
I am self-aware enough to know when my work stinks. openapi-changes has a lot of promise, but misses the mark on too many points to be truly useful.
It does work, but the harder you look, the more holes appear.
The code is a tangled mess. I once had an engineer look at it, then slowly back away while making polite excuses. I don’t blame him. I didn’t have a design in mind when I started sketching the code. It just flowed like poetry as I wrote it.
The poem was horrible and confusing. Reading it back was painful.
But the internet liked it!
It had over a million downloads. It shows that the tool is valued and useful.
After stabilizing it and adding some early community feedback, I kind of just… ignored it and left it alone, that was a bad idea.
Bugs, Vulns, and Features - Oh My
Focused deeply on building out the core of the OpenAPI Doctor in 2025, I let openapi-changes rot. Software rots fast when you stop tending to it.
We call it ‘bit rot’ in the industry.
A glorified tech demo
The tool was really just a way to stress-test the core engine (libopenapi). It was never intended to end up in the form it was in. For one, the HTML report was built using an incompatible stack compared to the rest of the pb33f toolchain.
But that scratchy code laid the foundation for the rest of pb33f.
Building out the graph’s visual experience (and a companion tree) taught me everything there was to know about how it all worked. Once completed and shipped, it was time to start on the long-term vision.
A total rebuild of everything, everywhere, all at once
The OpenAPI Doctor implements the exact same explorer idea openapi-changes does, except for a few major differences.
- It’s designed to be flexible against multiple model types.
- We don’t use React anymore; we use web components at pb33f.
- Except for ELK.js, it’s custom-built from the ground up.
ELK stands for Eclipse Layout Kernel. I kid you not, it’s a Java layout engine for Eclipse that was compiled to JS using GWT (Google Web Toolkit).
It took me over a damn year to get this thing right. It’s really hard to build a graphing engine and model that works across multiple interfaces and handles graphs composed of thousands of files.
An engine that would work with a document, or a change set, or both, or a subset of a model, something that could render in a TUI, markdown, or a web UI using SVG and HTML.
It may have looked like things were quiet with openapi-changes, but in reality, they were anything but. I was working on the following:
- libopenapi
- the doctor library
- the doctor platform (closed source)
- UI components for the stack (closed source)
- vacuum
All at the same time, all of them connect together. The doctor library powers it all.
50GB of YAML
Can you imagine?
Shortly after deploying the OpenAPI Doctor, with the change detection features in preview in the fall of 2025, storage use started to skyrocket.
Hundreds of MB were being stored for power users, and that storage was growing daily.
The graphing was half-working, with data duplication everywhere, and the rendering engine was showing everything in the graph at once.
Not great, but not entirely terrible either.
As data use skyrocketed, some profiling was called for, and two issues jumped out immediately:
- The graph was printing itself recursively with each node, and this compounded at scale (yikes)
- 5x duplication when saving all files.
It forced me to spend days refining, tuning, fixing, testing, and hacking on this system, stabilizing it, reducing its footprint, and speeding up its rendering, ensuring it was accurate and, most importantly…
Useful as a tool for exploring the data.
It had to be right, otherwise there was no point in doing any of this work.
A stack of building blocks
In March 2026, pb33f very quietly released features and upgrades to the OpenAPI Doctor (that are all unannounced at the moment).
I’ll leave that content to another article.
But what is important is that it includes all of the machinery for the birth of new tools, as well as the rebirth of old ones.
Most importantly, the tuned and fixed graph/model/explorer combined with all the new change-rendering built for the OpenAPI Doctor, was now available for use. Ready to be reboxed into all sorts of useful tooling.
So many subsystems
One key item missing was a custom file revision system that allowed libopenapi to look up references across commits. This is something that was already developed for the OpenAPI Doctor to allow revisions to be tracked across repos or databases.
It’s key because without it, any parsing library has no idea what to do when it encounters a $ref (JSON Pointer Reference) to an external file that no longer exists in the file system.
A change made to a spec a year ago points to files that were moved or deleted a long time ago, without the parser knowing how to look up a reference from a specific Git commit in time when looking for that JSON pointer - you can’t build a time machine that spans across a file system that changes over time.
From the outside, it must have looked like openapi-changes had been abandoned, but on the inside, it had been consuming huge cycles of my brain for over a year.
Strangler Fig
Without announcing any of the new features, it was time to fix the rotting corpse I had left out in the sun.
There was no saving the codebase; most of it had already been rewritten upstream anyway.
It had to be a complete rewrite downstream as well.
It had to be backward-compatible with the old CLI, built on top of the existing capabilities, whilst also completely replacing them. This is kind of hard to do ‘in-place’, but there is an architectural technique I use that makes it easier.
The Strangler Fig pattern is something I use in these situations. Essentially, as the new system grows alongside the old while they both still operate, the new system gradually obscures the old, allowing it to be dismantled. The system stays operational while two codebases coexist.
Just before release, openapi-changes was running two feature sets in parallel. All the new code was prefixed with new-, which allowed me to perform detailed side-by-side comparisons of the features.
Harder, Better, Faster, Stronger
It is materially better in every direction that matters. More results, better organized, correct multi-file support and more control.
All the interfaces are covered! HTML, Markdown, JSON, and Terminal UI.
The Console TUI
The console terminal UI is beautiful and now aligned with the new vacuum console, making it far easier
to navigate huge change sets in the terminal.
The visual style and the architecture have been aligned with vacuum and the two can now work together.
The Terminal Summary
The summary is richer now, with a much more detailed view of the change tree and overall totals.
A quick way to see what has changed
The Markdown Report
The markdown-report has gone from basic output to something properly useful. It now produces a real changelog for a changeset, not just a dump of information.
Pièce de résistance
The best part is the all-new html-report.
It folds in the timeline, explorer, diffing and markdown reporting into a single experience, whether comparing a simple left/right pair or tracking changes over time.
Expand and explore visually, click nodes, click the tree, see the change rendered and a focused diff in the right hand panel.
A new timeline experience that mirrors OpenAPI Doctor
Diff with focus, switch to a full file view, explore the change set visually, inspect individual objects with targeted diffs and rendered changes, and view the changelog as HTML with optional list-based views.
The markdown report is also available as a change report, rendered into HTML and styled.
markdown-report is rendered into HTML inside the HTML report. A report inceptionI think it looks great, and it ships with three pb33f themes built in across the product line: Dark Mode (pb33f), Roger Mode (light / monochrome), and Tektronix (retro green phosphor).
Tektronix mode makes me want to shout ‘I’m in.’
v0.2 of openapi-changes is now available.
Upgrade using whatever method you originally used to install it, and the new experience is ready to go.
If you have never used it, what a great time to give it a try!
All new license
I’ve moved openapi-changes to Apache 2. It’s no longer GPL!
Don’t take my word for it.
