DEV Community

Vivian Voss
Vivian Voss

Posted on • Originally published at vivianvoss.net

The Update Treadmill

Split illustration: Left side shows a developer trapped in a hamster wheel made of error messages, build failures, and update notifications (red-tinted chaos). Right side shows the same developer sitting calmly at a minimal desk with a single terminal and coffee (green-tinted calm). Text overlays compare framework update maintenance (75% of dev time) with SQLite's backwards compatibility since 2004, pledged to 2050.

Beta Stories — Episode 06

Your software worked on Friday. You ran npm update on Monday. It no longer works on Monday. Nothing in your code changed. Not a single line. The platform moved underneath you.

One does find it rather charming that the industry calls this "progress."

The Promise

"Ship early, iterate fast, embrace change." Agile taught an entire generation that stability is something to overcome. Sprints replaced milestones. Continuous deployment replaced releases. The word "done" quietly left the building and has not been seen since.

The ecosystem took the hint. Angular ships a new major version every six months. Eighteen major versions in ten years. Each with breaking changes, each with an 18-month support window, each politely informing you that the version you spent three months migrating to is now approaching end of life. You are not building software. You are servicing a subscription to your own framework.

The build tools followed suit. Grunt was the standard in 2013. Gulp replaced it by 2015. Webpack took over by 2017. Now it is Vite, with Webpack satisfaction down to 26%. Four generations of tooling in ten years, each requiring its own configuration language, its own plugin ecosystem, its own mental model. The code you built did not change. The machinery around it was replaced four times.

The Decay

44% of breaking changes in npm packages arrive in minor and patch releases. The versions that semantic versioning promises are safe. They are not. They merely look safe, which is rather worse.

Next.js 15 reversed its caching defaults. Code that relied on cached responses now fetches on every request. Next.js 16 dropped Node.js 18 entirely. One does not recall requesting either of these changes, yet here one is, updating CI pipelines on a Tuesday afternoon.

The migrations that do get announced fare little better. Python 2 to 3 took twelve years. Twelve years for a language migration that was meant to be straightforward. The cost to the industry has been estimated at over $100 billion. AngularJS reached end of life in 2021. Four years later, 1.2 million websites still run it, with 419,000 weekly npm downloads. The migration was not completed. It was abandoned.

Stripe measured the damage in 2018: developers spend 33% of their time on technical debt. 13.5 hours per week per developer on inefficiencies that produce no value. Across the industry, 75% of development time goes to maintenance. Not features. Not innovation. Keeping the treadmill running so that one may continue running on the treadmill. Splendid use of engineering talent.

The Mechanism

Framework authors need adoption. Adoption requires novelty. Novelty requires breaking the previous version. Break, migrate, break, migrate. The cycle is not accidental. It is the product.

Agile provided the philosophy. "Embrace change" became "inflict change." Sprints guarantee a next iteration, never a stable release. The process ensures that software never reaches a finished state, and the vocabulary ensures nobody notices: it is not instability, it is iteration. It is not churn, it is evolution.

And the tooling enforces it. Dependabot opens 200 pull requests per week for a monorepo. Not because your code is broken. Because a dependency four levels deep released a patch for a vulnerability in a function you do not call. The automated pull request arrives, the CI runs, the reviewer spends twenty minutes verifying that nothing changed, and the treadmill advances one step. Multiply by fifty projects and you have a full-time job that produces nothing.

The Signal

SQLite has maintained backwards compatibility since 2004. The developers have committed to preserving the current file format, SQL syntax, and C API until the year 2050. That is not a version policy. That is a promise to every system that depends on it.

POSIX has been stable since 1988. Thirty-eight years of API consistency across operating systems, vendors, and hardware architectures. A shell script written in 1990 still runs.

FreeBSD has maintained source compatibility across major releases for over thirty years. Code written for FreeBSD in the 1990s compiles and runs on FreeBSD 14 today. Not because nobody touched the system. Because every change was made with the understanding that other people's software depends on it.

These are not legacy projects. They are proof that stability is a design decision, not a technical limitation. The treadmill is not inevitable. It is profitable.

Your framework updates every six months. Your database file format has not changed in twenty-two years. One of them understood what "production" means.

"Go into frameworks," they said. They did not mention the frame gets replaced every six months whilst you are still hanging in it.

Read the full article on vivianvoss.net →


By Vivian Voss — System Architect & Software Developer. Follow me on LinkedIn for daily technical writing.

Top comments (0)