I read a lot of “vibe coding technical debt” pieces the way I read a weather report for a city I don’t live in: true, generic, and no help for deciding what to do this afternoon. Every one of them agrees the debt is real and prescribes the same fix regardless: a PR process, a second reviewer, a spec written before the agent builds, the kind of governance that assumes a team standing behind the code. None of them hand you a number for your own repository, and none of them are written for the person who built the thing alone.
Across the 26 apps AxonBuild has audited in June and July 2026, the median production-readiness score is 51 out of 100. Narrow that to the 21 third-party apps in the corpus and the debt concentrates in a specific place: the pillar that grades how extendable the code is, Maintainability & Evolvability, comes in at a 61.1 average, near the top of the twelve; the pillar that grades whether anything catches a mistake, Reliability & Correctness, comes in at 31.4, dead last. Read plainly, that split is the whole finding: the code you can see mostly holds up, and nothing stands behind it to say when it stops.
So yes, AI-generated code carries more technical debt than code a team reviewed line by line, and that debt mostly lives outside the file you’d open to find it: in what was never tested, never watched, and never checked against what shipped last week. The rest of this post is a way to put that on your own repo tonight, and an order to pay it down in, without a team.
What the 61.1 and the 31.4 actually measure
Maintainability & Evolvability is a proxy for how easy a codebase is to extend: module boundaries, naming, how far a change in one place ripples to another. A 61.1 average across the third-party corpus means most of these apps pass that proxy well enough. Ask an assistant to add a feature and it usually finds somewhere to put it.
Reliability & Correctness asks a different question: does the app catch its own mistakes, and does anything notice when it doesn’t. A 31.4 average, the worst pillar scored, means most of these apps fail that question badly. The two numbers sit nearly thirty points apart in the same repositories, sometimes in the same file.
I saw a small version of that gap auditing a motorsport dashboard, no criticals, a score of 63. Two of its near-identical table components had already drifted apart: a favorite-toggle feature landed on one twin and never made it to the other, so two views built from the same copied component behave differently today. Nothing failed when that shipped, because nothing was built to notice a difference between components that started out as copies of each other. It read as one of the more finished apps in the corpus, right up until you compared the twins.
How to measure technical debt in AI code
Measuring technical debt in AI-generated code takes three numbers from your own git history: the god-file line count, the files churned most in the last month, and the function names defined more than once. Each command takes under a minute, and together they tell you most of what a full audit would.
- 01 God-file line count: rank every source file by line count. One file at three or four times the size of its neighbors is a god-file candidate, and every god file is debt hiding where nobody has to look for it
- 02 Churn: rank files by how many times they were touched in the last month. A file revised five times in a week under commit messages like fix, fix again, and revert is a doom loop, not routine iteration
- 03 Duplicated logic: count function and component names defined more than once. Every count above one is a copy of some logic waiting to drift from its sibling, the way the motorsport dashboard's table twins already had
# biggest files (god-file candidates)
git ls-files '*.tsx' '*.ts' | xargs wc -l | sort -rn | head
# churn: files revised most in the last month
git log --since='1 month ago' --name-only --pretty=format: | sort | uniq -c | sort -rn | head
# duplicated logic: function/component names defined more than once
grep -rhoE '(function [A-Za-z0-9_]+\(|const [A-Za-z0-9_]+ ?= ?\()' src | sort | uniq -c | sort -rn | awk '$1>1' | head
Swap the file globs and the src path for whatever your project actually uses (.py, .rb, app/ instead of src/) and run all three. A clean result reads short and boring: no file wildly bigger than the rest, a churn list with no repeat offenders, no duplicate name showing up more than once. Most vibe-coded apps don’t read boring on the first try.
Reading your number
AI-generated code technical debt bills you on three different clocks. A god file costs you slowly. Every edit inside it risks something two screens away, so a feature that took an afternoon in month one takes two days by month four, and you start avoiding whole sections of your own app. A churn spike costs you now: five reverts on the same file in the same week means the assistant is guessing, not fixing, and the seventh attempt won’t hold any better than the first. Duplicated logic costs you invisibly: the day the two copies disagree is the day a user lands on whichever copy you didn’t just update, and there’s no error for that, only a support message that reads like a mystery.
None of these three show up in a demo, the same way debt hides behind an 818-line test suite that never once executed the checkout it was written to cover: a codebase can look finished and still be flying blind. It’s also why the mechanism behind the number matters: prompt-built code is bolted onto the last generation with nobody holding the whole thing in their head, so the debt starts accumulating in week one.
Performance debt wears the same shape with a different symptom. A missing connection pooler or an unindexed foreign key, the wiring behind an app stalling at 100 concurrent users, stays invisible until load forces the issue. Maintainability debt and performance debt both fail quietly, and neither shows up in the screens you’d show an investor.
The debt in AI-generated code looks like a clean diff, sitting on top of a test that was never written.
How to fix technical debt in AI code without a team
Paying down technical debt in AI code without a team follows a specific order: pin two or three tests to the flows that move money, split the worst god file the next time you’re already in it, then consolidate the worst duplication. It doesn’t start with starting over.
- 01 Pin the money paths first. Two or three tests on signup, checkout, and whatever flow moves money or data across a boundary cost about an afternoon and catch more than a week of manual review would
- 02 Split the worst god file the next time you're already in it, not on a dedicated cleanup day that never arrives. Pull it apart along whatever seam the current feature already needs: one piece for data-fetching, one for the business rule you're changing, one for the render
- 03 Consolidate the worst duplication once you've found it, not all of it at once. If your grep turned up the same function defined four times, keep the one everyone will find next, delete the other three, and update the handful of call sites that pointed at them
Do the three in that order, because each one makes the next one cheaper. A pinned test tells you the god file split didn’t break the money path, and once those tests exist, naming the file and the command that protects it is what belongs in a CLAUDE.md so the assistant stops re-opening the same debt next week. A god file that’s been pulled apart is easier to grep for the duplicate you’re about to consolidate. None of it requires a rewrite, a rebuild, or a second engineer; it requires doing the next item on the list the next time you’re already touching that part of the app.
If you’d rather have the number handed to you instead of running the commands yourself, a Beyond the Demo Audit puts a figure on the god files and the churn and hands you the order to work them in, tied to a file and a line. Paying your own debt down is one slice of whether the app is ready to launch at all; inheriting someone else’s vibe-coded app instead of carrying your own vibe coding debt forward is a related but different job, closer to a first-week audit than an ongoing gauge.
What to ignore
Not everything a grep turns up is worth an afternoon. Style disagreements, folder-naming conventions, and a coverage number chased for its own sake feel like progress while reducing no risk. A rename that touches forty files and changes nothing about what the app does is the kind of pay-down that feels productive and buys nothing back.
The same restraint applies to duplication. Two similar-looking components are not automatically debt. An admin view and a public view are allowed to diverge on purpose, showing different fields to different roles, and consolidating those two on principle is what creates the bug the self-measure was supposed to prevent. The three commands only flag where to look. Whether a given god file or a given duplicate is actually costing you something stays a judgment call only you can make.
Common questions about technical debt in AI-generated code
Is AI-generated code more technical debt than human code?
Yes, and the 26-app corpus behind this post gives that answer a specific shape. The median score across the 26 audited apps is 51 out of 100, and across the 21 third-party apps the debt piles up on one side: a 61.1 average for Maintainability & Evolvability against a 31.4 for Reliability & Correctness, last of the twelve pillars. The structure of the code is usually fine. Nothing in these apps was built to notice when the structure stops matching reality.
How do I measure technical debt in AI code?
Run three commands against your own git history: rank files by line count to find god-file candidates, rank files by how often they were touched in the last month to find churn, and grep for function or component names defined more than once to find duplicated logic. Each one takes under a minute and needs nothing beyond git and the standard Unix tools already on your machine.
Can I pay down AI technical debt without a team?
Yes, in a specific order: pin two or three tests to the flows that cost money, split the worst god file the next time a feature already has you in it, then consolidate the most duplicated logic you found. Each step makes the next one cheaper, and none of them require a second reviewer or a dedicated cleanup sprint.
Is AI-generated code maintainable?
Often, yes, more than its reputation suggests. Maintainability & Evolvability came in at 61.1 out of 100 across the third-party corpus, healthier than most of the twelve. The risk sits elsewhere: Reliability, the pillar measuring whether anything catches a regression, averaged roughly half that, 31.4. A maintainable-looking app can still ship untested changes with nothing to flag when one breaks something else.
Don't guess where you stand.
The free 2-minute Beyond the Demo Scorecard estimates where you stand across 12 readiness areas and shows what to check first.