Breaking Changes started as a web app, the way everything I build starts as a web app. Paste a GitHub repo, pick the version you’re on and the version you’re scared of, and it collapses everything between them — fifty releases of changelog, sometimes more — into an upgrade plan a team can actually run. The first commit is from April 2025, and it claims the repo is “in a working state.” That was optimistic.
The app is free, and free tools can’t pay for inference. So it’s bring-your-own-key: you paste a key from OpenAI, Anthropic, Google, or Mistral, and you pay your provider directly for what the analysis costs. Which meant strangers’ API keys were now passing through my code, and handling that properly became the most careful engineering in the product. Keys default to sessionStorage and die with the tab. Persisting one is an opt-in toggle, per provider, cleared after 24 hours of inactivity. The server is a transit proxy: it forwards your Authorization header to the provider you picked and forgets it. Error logs strip known key prefixes before they’re written, because something will eventually crash mid-request and a stack trace shouldn’t be worth money.
All of that protects a credential that’s in flight for maybe thirty seconds. None of it is the product. It’s rent: the cost of borrowing someone else’s intelligence.
Then in June I finally asked the question I should have asked in April 2025. Who needs an upgrade plan, and where are they sitting when they need it? In a terminal, inside the project that’s about to break. And these days there’s a decent chance a coding agent is open in that terminal: an authenticated, already-paid-for model, sitting in the exact codebase the plan is for.
So I repackaged the workflow as a Claude Code skill. It’s two files. SKILL.md is 118 lines of instructions; the fetch script is 264 lines of Node with zero dependencies, the same one that backs the CLI. When it runs inside the agent, the custody problem doesn’t shrink. It’s gone. There’s no key to paste, because the agent is the model, and nothing leaves the machine except changelog fetches to api.github.com. A year of careful key handling, replaced by a markdown file.
I know how that sounds. I wrote the key handling.
The port was cheap because of a line I’d drawn much earlier, for a different reason. Fetching and aggregating changelogs is deterministic — resolve the range, pull the releases, flag the breaking changes — and I kept that half dependency-free so the code touching your key would be small enough to audit in one sitting. That was a trust decision. It turned out to be the distribution seam. The web app plugs a provider call into the intelligent half; the CLI plugs in nothing and emits JSON; the skill plugs in whoever happens to be reading the instructions.
node bin/fetch-changelogs.mjs facebook/react --pkg react --json
Here’s the part that stung a little. The skill isn’t a lighter version of the web app. It’s better. The web app only knows changelogs; it can’t see your code, so its advice tops out at well-organized generalities. The agent reads your installed version out of package.json, greps for call sites of the API that got removed, and writes action items with your file names in them. I can’t ship that in a browser tab at any budget.
It’s not all solved. There’s no registry for skills, so installing mine means copying a folder into ~/.claude/skills, and discovery means hoping an awesome-list maintainer merges your PR. Nothing pins a skill version to a script version. And the script’s sharp edges travel with it: GitHub’s tag API isn’t chronological, so a repo without releases can miss your range entirely, and a security patch back-ported after a later major lands in the wrong slice of the timeline. I wrote all of this into SKILL.md, and something strange happens there — the reader of the documentation is the runtime. The doc says to fall back to git when the tag window misses, and the model does.
For twenty years the question for a developer tool was: how do I get people in front of it? I think the better question now is where the intelligence already lives, and what’s the smallest thing you can ship into it. For Breaking Changes the answer was 382 lines. The web app stays; it’s the demo you can send as a link. But the best version of this thing I built isn’t a website.
Twenty years in, that’s a strange sentence to type. I expect it gets less strange from here.