Something interesting is happening. A false narrative is spreading online, pushed by people who know little about engineering, and others who should know better.
They claim junior devs are now 10x more productive, and project managers are shipping code themselves. Now, close your eyes for five seconds and try to picture what that code looks like. It's 100% legacy, disposable code.
The problem isn't AI, or PMs turning Figma into code, or junior devs prompting like mad. The real problem is the disconnect between expectations and outcomes. And that disconnect exists because people are mixing up terminology that took engineers years to define properly.
- A lean prototype is not the same as a disposable prototype
- An MVP is not the same as a lean prototype
- And a product is not the same as an MVP
A lean prototype is a starting point, a rough model used to test and refine an idea. If it works, it might evolve into an MVP. An MVP becomes a product once it proves the core assumptions and shows there's a real need in the market. And a disposable prototype is exactly that, something you throw away after initial use.
Vibing tools are great for building disposable prototypes, and LLM-assisted IDEs are better for creating actual products. Right now, only engineers are able to create lean prototypes using LLM prompts outside the IDE. Everyone else is just building simple (and working?) software on top of disposable code.
I had a PM at my company (with an engineering background) post AI generated slop in a ticket this week. It was very frustrating.
We asked them: "Where is xyz code". It didn't exist, it was a hallucination. We asked them: "Did you validated abc use cases?" no they did not.
So we had a PM push a narrative to executives that this feature was simple, that he could do it with AI generated code: and it didn't solve 5% of the use cases that would need to be solved in order to ship this feature.
This is the state of things right now: all talk, little results, and other non-technical people being fed the same bullshit from multiple angles.
I think you are not going far enough though: All code is legacy code. So vibe coding's ability to make writing more code faster isn't special because it's code nobody understands: Your hand-rolled code is also bad.
Once you embrace the fact that all the code is legacy, then it's clear how writing more code, faster cannot be helpful from a maintenance POV: You are just creating more work for yourself.
And no, libraries don't really solve the problem, but might make it a bit less so if they are well maintained, because hopefully then they are someone else's problem. Eventually it can be mostly trusted and be almost not legacy. But a library that changes too often, or has a bad interface, is just legacy code which you also cannot change easily for a double whammy.
The more one writes code, the more one eventually realizes that the one way out of the problem is doing less: Not necessarily you, but just needing fewer things, in general. Because all complexity is ultimately a puzzle for someone that doesn't remember, and that's probably you a week later, or even in the way you typed it, as what you thought were the requirements might not really have been the requirements. And even if they were what a supposed expert told you they should be, that doesn't mean that whoever told you was right, and that's true even when you are the supposed expert.
This is really clear and well argued. I particularly enjoyed this line:
> If you don't understand the code, your only recourse is to ask AI to fix it for you, which is like paying off credit card debt with another credit card.
And what you will get in return is professional software developers looking at vibe-coded modules that already went into production, stating that "we will never ever touch this", as they don’t want to be responsible for something they would have never put into production in the first place.
Now, they see themselves challenged to defend against the non-technical departments, because all they see are some elitist developers, that deem something as "not good enough", which, from a user standpoint, "is working quite well".
However - it's unmaintainable. That whole situation is a mess, and it's becoming bigger and bigger.
I ran into an AI coded bug recently the generated code had a hard coded path that resolved another bug. My assumption is the coder was too lazy to find the root cause of the bug and asked the LLM to "make it like this". The LLM basically set a flag to true so the business logic seems to work. It shouldn't have got past the test but whatever.
In another code base, all the code was written with this pattern. Its like the new code changed what the old code did. I think that 'coder' kept a big context window and didn't know how to properly ask for something. There was 150 line function that only needed to be 3 lines, a 300 line function that could be done in 10 etc. There were several a sections where the LLM moved the values of a list to another list and then looped through the new list to make sure the values were in the new list. It did this over and over again.
I'm seeing a real-world example of Jevons paradox playing out here. When AI coding tools first emerged, everyone predicted mass developer unemployment. Instead, I'm watching demand for skilled developers actually increase.
What's happening is that all this "vibe coded" software needs someone to fix it when it breaks. I've been getting more requests than ever to debug AI-generated codebases where the original "developer" can't explain what any of it does. The security audit work alone is keeping me busy - these AI-generated apps often have vulnerabilities that would never pass a human code review.
It reminds me of when WordPress democratized web development. Suddenly everyone could build a website, but that just created a massive market for developers who could fix broken WordPress sites, migrate databases, and patch security holes.
The difference now is the scale and complexity. At least with WordPress, there was some underlying structure you could reason about. With vibe coding, you get these sprawling codebases where the AI has reinvented the wheel five different ways in the same project, used deprecated libraries because they were in its training data, and created bizarre architectural decisions that only make sense if you don't understand the problem domain.
So yeah, the jobs aren't disappearing - they're just shifting from "build new features" to "fix the mess the PM made last weekend when they tried to ship their own feature."
> We already have a phrase for code that nobody understands: legacy code.
Wow, no. Bad misunderstanding of what legacy means.
Long-lived organizations all eventually go through tech renovations, where they re-platform their business functionality onto more modern systems. But sometimes, the cost/benefit analysis to that re-platforming doesn't make sense... yet. The pieces of the business still running on the former platform are legacy code.
People do understand it. Often, deeply understand it because they wrote it, and have lived and supported it for years. They know the reason behind the tech debt, all the odd tech constraints that drove it to where it is, they can keep the thing running without breaking a sweat. It is second-nature to them.
But it is not easy for anyone other than them. That is the true risk of legacy code, and that is probably where the author got off-track. They may have only ever worked in orgs after the last of the legacy coders left, and everything was a disaster. You definitely do not want to let a legacy system get to that point... and at the same time, if you ever do get there, the cost/benefit analysis has changed and you need to retire the legacy stack.
All that being said, now, yes, we can compare it to vibe coding. If nobody understands the code from the beginning, you never have that magical timeframe when someone just keeps the system alive with ease. You never solved business problems with it. It is just bad code launching straight into the disaster-filled zone where nobody can maintain anything.
Yesterday, I wrote detailed requirements for a bit of software, and sent Claude to work. The code looked great until it…didn’t. It ended up being completely unworkable.
I’ve noticed myself writing requirements for a feature and asking Claude to help me think through and expand. Obviously in a real project, there are challenges:
(1) how do we tell Claude what is already in the project so it doesn’t reimplement existing methods?
(2) how do we get Claude to fully implement the feature and not just “stub it out?”
(3) how do we help Professionals maintain visibility and digest the new code?
Claude recommends the explore-plan-code-commit loop. I’m working on a package which formalizes that process within a Laravel application.
This has happened before. Non-technical or junior people developed and deployed applications, emboldened by the relative ease of Microsoft Access and Excel. There were all kinds of limitations, scaling problems, and maintenance nightmares. But there were a lot of upsides too, and it made the "professionals" up their game to obviate the need for such adhoc and unsanctioned developments.
Come to think of it, the exact same thing happened when the PC became popular. Mainframe people were aghast at all the horrible unprofessional mess that the PC people were creating.
A lot of my work early on in new projects is setting up local and CI validations and rules, practices, reviews, git usage, design patterns / code architecture, etc - skipping all of those will lead to maintenance problems in the long run, whether code is written by a developer (I'm not even going to prefix it with 'junior' because I also suck lol) or an AI. But that validating is carried by the whole company at least. Where I work now we've got unit tests, linters, automatic formatting via Biome or Prettier, visual regression tests, Sonar with all the options enabled, minimum of two code review approvals, locked down main branch, etc etc etc.
Some AI generated code does come through, but at that point it's already mostly alright. Code review is still required for things like unnecessary comments or detecting duplicate functionality (exact duplicate code is already pointed out by Sonar).
What I encounter, instead, are lashups that the engineering team thought would be throwaway, but which Management made "Final Ship" code.
I have learned to always do "ship-shape" code; even for the most innocuous projects. I may be a bit sloppy as I'm exploring different paths, but the minute I decide on a firm plan, the code cleanup and documentation starts.
interesting but i have thought about it. rarely is ours as well. All my code is original but based on my past experiences from learning, thinking about it, and improving it based on new knowledge i know. my 2cents.
IMO, the time of "code as math" is over. No sufficiently large software system that interacts with the real world is provable to be correct like a mathematical statement is. They are all complicated, engineered systems that are backed by a mix of formal guarantees, earned design principals, experimental testing, rules of thumb, acceptable performance envelopes, etc
This is what all software will become, down to the smallest script. The vast majority of software does not need to be provably correct in a mathematical way. It just needs to get the job done. People love the craft of programming, so I get it, it's uncomfortable to let go.
But what is going to win out in the end:
- An unreadable 100K loc program backed by 50K tests, guaranteeing behavior to the client requirements. Cost: $50K of API tokens
- A well engineered and honed 30K loc program, built by humans, with elegant abstractions. Backed by 3K tests. Built to the same requirements. Cost: $300K of developer time.
If I am a consumer of software, and not particularly interested in the details, I am going to choose the option that is 6x cheaper, every time.
This assumes software is a thing you build once and seal it off when it's finished.
What happens when you need to modify large portions of it? Fix security issues? Scale it up 20x? You can throw more tokens at it and grow it into a monstrous hulk. What if performance degrades due to its sheer weight?
I know humans aren't perfect and are capable of writing really bad unmaintainable code too, but this is just embracing that more. This feels like going further down the same route of how we ended up with 10MB websites that take many seconds to load. But yeah it will probably win over the market.
> An unreadable 100K loc program backed by 50K tests, guaranteeing behavior to the client requirements. Cost: $50K of API tokens
As my team has spent the past several months trying to explain to upper management, you can't guarantee that the program does what the client wanted just by adding more tests.
If the AIs ever become capable of reliably producing what the client wanted, they will win. But I'm not convinced they will. They might be able to produce what the client asked for, but programmers have known for decades that that's pretty much useless.
If the code will be reviewed from the LLM of the future, then why does it matter? Let it review a trillion lines of code for a simple calculator app.
I think that we devs are now very skeptical because we are the ones that have to fix the sh that llms spit out. But likely we will be taken out of the loop completely.
When you have 100+ tables and 100k+ loc you’re incapable of the context needed to write features without bugs which is why we have tests. LLMs are capable of like 5% of the context you are:
Full context > human context capacity > LLM context capacity.
We should all be able to agree on this and it should settle the debates around the efficacy of vibe coding.
We’ve gone from tiny context windows to 1 million tokens in a couple of years. At this rate LLMs will exceed human context and grow to have full context.
Coding with AI is just a different kind of work than what those of us that coded before AI are used to doing. But, reading and understanding the code AI produces is required for anything complex. I had an inventory control app that I started five years ago without AI and picked the project back up this year. I had like 15-20 database tables in the app when I started with AI this year. Now, I have a "platform" database, a "tenant" database, about 125 tables in the tenant database and 30 in the platform database, full test suite that integrates both databases, like 100 services, etc., it would have taken me *YEARS AND YEARS* to do what I've done in the last 90 days with AI assistance. The biggest challenge has just been keeping up with all the code output and ensuring no technical debt accrues and it is all leveraging existing code. Ultimately, you have to understand what you've already built to ensure the AI uses it instead of constantly reinventing it. But, generating what would have taken years of my life in a few months? PRICELESS.
I don't agree with this, my code quality is much better now. But you have to stay on the LLM's ass in terms of guidance and review it all (this is a given). I think part of it is the LLMs writes more "standard" code instead of getting creative with architecture, etc. It helps to create guides and correct context, proper test coverage just as you would if working with other people.
Everything exists in four dimensions (space + time). If a thing “looks good” in three of them but falls apart in the fourth (e.g., it works right at this moment but its continued existence is an impossibility or a hassle—be it physical artifact made from subpar material, unmaintainable tangle of excess code, etc.), then that thing does not look good. Getting a hang of what things look like in the fourth requires skill and wisdom that probably partly comes from having traveled it yourself.
132 comments
[ 2.8 ms ] story [ 101 ms ] threadThey claim junior devs are now 10x more productive, and project managers are shipping code themselves. Now, close your eyes for five seconds and try to picture what that code looks like. It's 100% legacy, disposable code.
The problem isn't AI, or PMs turning Figma into code, or junior devs prompting like mad. The real problem is the disconnect between expectations and outcomes. And that disconnect exists because people are mixing up terminology that took engineers years to define properly.
- A lean prototype is not the same as a disposable prototype
- An MVP is not the same as a lean prototype
- And a product is not the same as an MVP
A lean prototype is a starting point, a rough model used to test and refine an idea. If it works, it might evolve into an MVP. An MVP becomes a product once it proves the core assumptions and shows there's a real need in the market. And a disposable prototype is exactly that, something you throw away after initial use.
Vibing tools are great for building disposable prototypes, and LLM-assisted IDEs are better for creating actual products. Right now, only engineers are able to create lean prototypes using LLM prompts outside the IDE. Everyone else is just building simple (and working?) software on top of disposable code.
We asked them: "Where is xyz code". It didn't exist, it was a hallucination. We asked them: "Did you validated abc use cases?" no they did not.
So we had a PM push a narrative to executives that this feature was simple, that he could do it with AI generated code: and it didn't solve 5% of the use cases that would need to be solved in order to ship this feature.
This is the state of things right now: all talk, little results, and other non-technical people being fed the same bullshit from multiple angles.
Once you embrace the fact that all the code is legacy, then it's clear how writing more code, faster cannot be helpful from a maintenance POV: You are just creating more work for yourself.
And no, libraries don't really solve the problem, but might make it a bit less so if they are well maintained, because hopefully then they are someone else's problem. Eventually it can be mostly trusted and be almost not legacy. But a library that changes too often, or has a bad interface, is just legacy code which you also cannot change easily for a double whammy.
The more one writes code, the more one eventually realizes that the one way out of the problem is doing less: Not necessarily you, but just needing fewer things, in general. Because all complexity is ultimately a puzzle for someone that doesn't remember, and that's probably you a week later, or even in the way you typed it, as what you thought were the requirements might not really have been the requirements. And even if they were what a supposed expert told you they should be, that doesn't mean that whoever told you was right, and that's true even when you are the supposed expert.
> If you don't understand the code, your only recourse is to ask AI to fix it for you, which is like paying off credit card debt with another credit card.
Now, they see themselves challenged to defend against the non-technical departments, because all they see are some elitist developers, that deem something as "not good enough", which, from a user standpoint, "is working quite well".
However - it's unmaintainable. That whole situation is a mess, and it's becoming bigger and bigger.
In another code base, all the code was written with this pattern. Its like the new code changed what the old code did. I think that 'coder' kept a big context window and didn't know how to properly ask for something. There was 150 line function that only needed to be 3 lines, a 300 line function that could be done in 10 etc. There were several a sections where the LLM moved the values of a list to another list and then looped through the new list to make sure the values were in the new list. It did this over and over again.
What's happening is that all this "vibe coded" software needs someone to fix it when it breaks. I've been getting more requests than ever to debug AI-generated codebases where the original "developer" can't explain what any of it does. The security audit work alone is keeping me busy - these AI-generated apps often have vulnerabilities that would never pass a human code review. It reminds me of when WordPress democratized web development. Suddenly everyone could build a website, but that just created a massive market for developers who could fix broken WordPress sites, migrate databases, and patch security holes. The difference now is the scale and complexity. At least with WordPress, there was some underlying structure you could reason about. With vibe coding, you get these sprawling codebases where the AI has reinvented the wheel five different ways in the same project, used deprecated libraries because they were in its training data, and created bizarre architectural decisions that only make sense if you don't understand the problem domain.
So yeah, the jobs aren't disappearing - they're just shifting from "build new features" to "fix the mess the PM made last weekend when they tried to ship their own feature."
Wow, no. Bad misunderstanding of what legacy means.
Long-lived organizations all eventually go through tech renovations, where they re-platform their business functionality onto more modern systems. But sometimes, the cost/benefit analysis to that re-platforming doesn't make sense... yet. The pieces of the business still running on the former platform are legacy code.
People do understand it. Often, deeply understand it because they wrote it, and have lived and supported it for years. They know the reason behind the tech debt, all the odd tech constraints that drove it to where it is, they can keep the thing running without breaking a sweat. It is second-nature to them.
But it is not easy for anyone other than them. That is the true risk of legacy code, and that is probably where the author got off-track. They may have only ever worked in orgs after the last of the legacy coders left, and everything was a disaster. You definitely do not want to let a legacy system get to that point... and at the same time, if you ever do get there, the cost/benefit analysis has changed and you need to retire the legacy stack.
All that being said, now, yes, we can compare it to vibe coding. If nobody understands the code from the beginning, you never have that magical timeframe when someone just keeps the system alive with ease. You never solved business problems with it. It is just bad code launching straight into the disaster-filled zone where nobody can maintain anything.
I've found it faster to have AI write the code, revise with instructions as necessary, and delve into the code itself if I need to.
I’ve noticed myself writing requirements for a feature and asking Claude to help me think through and expand. Obviously in a real project, there are challenges: (1) how do we tell Claude what is already in the project so it doesn’t reimplement existing methods? (2) how do we get Claude to fully implement the feature and not just “stub it out?” (3) how do we help Professionals maintain visibility and digest the new code?
Claude recommends the explore-plan-code-commit loop. I’m working on a package which formalizes that process within a Laravel application.
I really don't want to sign up for a service and then get my shit leaked immediately
Come to think of it, the exact same thing happened when the PC became popular. Mainframe people were aghast at all the horrible unprofessional mess that the PC people were creating.
Some AI generated code does come through, but at that point it's already mostly alright. Code review is still required for things like unnecessary comments or detecting duplicate functionality (exact duplicate code is already pointed out by Sonar).
I have seldom encountered these.
What I encounter, instead, are lashups that the engineering team thought would be throwaway, but which Management made "Final Ship" code.
I have learned to always do "ship-shape" code; even for the most innocuous projects. I may be a bit sloppy as I'm exploring different paths, but the minute I decide on a firm plan, the code cleanup and documentation starts.
This is what all software will become, down to the smallest script. The vast majority of software does not need to be provably correct in a mathematical way. It just needs to get the job done. People love the craft of programming, so I get it, it's uncomfortable to let go.
But what is going to win out in the end:
- An unreadable 100K loc program backed by 50K tests, guaranteeing behavior to the client requirements. Cost: $50K of API tokens
- A well engineered and honed 30K loc program, built by humans, with elegant abstractions. Backed by 3K tests. Built to the same requirements. Cost: $300K of developer time.
If I am a consumer of software, and not particularly interested in the details, I am going to choose the option that is 6x cheaper, every time.
People who work in formal verification will either vehemently disagree with you or secretly know you're right.
What happens when you need to modify large portions of it? Fix security issues? Scale it up 20x? You can throw more tokens at it and grow it into a monstrous hulk. What if performance degrades due to its sheer weight?
I know humans aren't perfect and are capable of writing really bad unmaintainable code too, but this is just embracing that more. This feels like going further down the same route of how we ended up with 10MB websites that take many seconds to load. But yeah it will probably win over the market.
As my team has spent the past several months trying to explain to upper management, you can't guarantee that the program does what the client wanted just by adding more tests.
If the AIs ever become capable of reliably producing what the client wanted, they will win. But I'm not convinced they will. They might be able to produce what the client asked for, but programmers have known for decades that that's pretty much useless.
What? It costs exactly $200
What’s the definition of “Legacy Code”? It’s code that has business value.
(otherwise you’d just delete it and move on)
I think that we devs are now very skeptical because we are the ones that have to fix the sh that llms spit out. But likely we will be taken out of the loop completely.
Full context > human context capacity > LLM context capacity.
We should all be able to agree on this and it should settle the debates around the efficacy of vibe coding.
With agentic programming, I need issue tracking that is accessible from CLI, and in three evenings I’ve made what would have taken two weeks.
The thing is, I would have just never finished it, or started in this case.