Vibe Coding cripples the mind
At a hackathon I helped host in November, I offered to help one of the teams finish their project. I opened their github repo and saw 50+ markdown files all in UPPER_CASE.md with names like QUICK_START.md SETUP_H100.md, basically any two word combination you can imagine. There were dozens of Python scripts in folders and sub folders, it was clear most of these were just meant to be used once, yet they lived right next to the gigantic 3 400 line main program file with a function called “setup_ssh_tunnel”. Somehow even more horrifying was the fact that it kind of worked. Their only problem was figuring out how to share it. So, I tried to help deploy it. Unfortunately, no one could tell me where the code for the actual website was. They did know it was somewhere in the folder though. After much trial and error, I eventually found it and deployed it and it only took three hours and 30% of my sanity.
The next day, I couldn’t stop thinking about the code I had seen. I wanted to know if the kind of vibe coding I saw that day was unique to this group or something that happens often. To find out I vibecoded a script that searches Github for repos made in the last 30 days, with zero stars, then sorts by most markdown files in the root directory of the repo. Here are the results. There are a good 30 repos that look exactly like the one I saw that day. Pictured above is how one of them looks.
RollerCoaster Tycoon, a video game from 1994, was made in assembly by Chris Sawyer. How this was done is beyond my comprehension. Today, nobody is making games in plain assembly and because of that games look and do things that would not have been possible in assembly. Grand Theft Auto 6 is coming out next year and the people making it will understand how to work with the game engine very well but almost certainly understand no assembly. At some point they will rely on a game engine to write the assembly for them. So to the extent we want people to push the frontier of video games, people ought to not program in assembly, even though this means game engines will write messy assembly and people will be worse at assembly.
Writing that sentence now seems obvious and stupid, who would care if the assembly a game ran on looked bad to human eyes. Who would study how good people are at assembly when aided by a compiler? Well it would be a people that thought knowing assembly is a virtue and getting a compiler to write assembly for you is not. It would be a world that viewed the inability to write good assembly as bad for a programmer’s soul.
It’s been just over a year since Andrej Karpathy coined the term vibe coding. On the 2nd of February 2025 he said: “There’s a new kind of coding I call “vibe coding”, where you fully give in to the vibes, embrace exponentials, and forget that the code even exists.”
Folks, I’m not here to mince words. The first year of vibe coding has been a disaster for humanity. Now, I will admit that there are some cute toy demos people have made. But these weekend side projects are not where I take issue. It’s the fact that new programmers are learning less than ever before because AI is assisting them with the important concepts required in thinking through hard problems. Because of this they are not developing the skills necessary to write and debug good code. What’s more, as we saw in the hackathon, the result of forgetting that code even exists is a project that is incomprehensible to humans. We are also now seeing empirical evidence of this, In a study conducted by Anthropic, they found that when comparing students using AI in a test versus those not “the AI group averaged 50% on the quiz, compared to 67% in the hand-coding group—or the equivalent of nearly two letter grades”[1]
There just are some fundamental things you need to know when coding and I do recognize that people have made similar arguments to this before and been wrong.
For example:
Or
Both of these are from Dijkstra in 1975.[2] In hindsight it’s pretty obvious that he was wrong. He clearly gave too much credence to the level of abstraction he had grown up learning, and therefore viewed the ones that came after it like Cobol with undue skepticism. I don’t know in what area he observed the crippled minds of cobol programmers. I assume it wasn’t in the cobol itself, but was judged when these programmers attempted to use something other than cobol and wrote sloppy code. And maybe the most natural language programming paradigm Python will one day fail but for now it seems to be doing okay.
What were the mistakes he made, then?
Well really it’s just a formal mistake in what he argues we should value when it comes to programming. You see it is almost certainly true that the more you use Python or COBOL the worse you get at C and assembly.
So if we had to write what he’s saying explicitly it’s something like:
COBOL sits above assembly
If you work at a higher layer you lose skills at the layer below
Using COBOL causes you to lose the skill of assembly
Therefore COBOL programmers aren’t as good at assembly
Knowing assembly is intrinsically valuable not just instrumentally valuable
Losing an intrinsically valuable skill is harmful
Therefore COBOL is harmful
In retrospect it’s pretty clear that knowing assembly isn’t intrinsically valuable for programmers, people can program extremely complex things without it. So really it’s trivially true that people are worse at Assembly when they use COBOL. The reason this caused people like Dijkstra to freak out is because he also assumed that proficiency in Assembly was a fundamental good and that the less of it a programmer had the worse off they were. He is not measuring what the programs people wrote did or how good they are or how fast they are, rather he is assessing how a layer he considers to be intrinsically valuable changed for the worse, to human eyes. So generically: Measure skills at abstraction layer N. Introduce a language at layer N+1. Find that N+1 users are worse at layer N. Declare this harmful.
Put like this it’s clear why Dijkstra was wrong about Assembly and Cobol but also why we are right about the dangers of vibe coding. At first glance it might seem like these are similar arguments:
Vibe coding sits above python
If you work at a higher layer you lose skills at the layer below
Vibe coding causes you to lose the skill of Python
Therefore Vibe coders aren’t as good at Python
Knowing Python is intrinsically valuable not just instrumentally valuable
Losing an intrinsically valuable skill is harmful
Therefore vibe coding is harmful
The difference is that Python is actually intrinsically valuable, and that’s why when “AI-assisted developers scored 17% lower” it is bad because they are losing an intrinsically valuable skill.
I realize that we have incorrectly predicted what is intrinsically valuable to programmers every single time. This time it’s obviously different though and we are right that anything above Python is harmful and ought to be avoided.
QED[3]
As a firm believer in the value of knowing Assembly, who always overperformed in and enjoyed the low-level programming language and systems courses back in college, I don’t necessarily think that switching over to compiled languages is responsible for the massive decline in optimization that we’ve seen from the software industry. There are plenty of great compiler programmers making sure that good code in C becomes good code in Assembly. I think the causes for that decline are sociological and human in nature, not technical—the proportion of programmers who are passionate about the field has steadily declined as CS became known as “the future” by everyone who didn’t know what they wanted to do for a living.
I would expect that this is also true for ‘vibe coding’. Programmers who care about their work will still do good work, but they’ll be diluted in the wider culture by people who can now produce lots of code but neither understand nor care about the notion of “good code”. It’s a matter of opinion whether the growth in accessibility is a worthwhile tradeoff for this culture shift, but the same discussion has been had about academia, the internet, and countless other things.
Insofar as the technical side goes, I’ve tried to keep fairly up-to-date on LLM coding progress, and I think that fully-automated refactoring of existing codebases, under normal circumstances, is something that we’ll see fairly soon. I’d expect that to solve the problem of giant, impossible-to-navigate slop repositories.
--
At the end of the day, I think that the other side of the problem—of new programmers not learning how to code—is a product of different sampling. Most of the slop programmers today would not have learned to code back in 1990. This is not to say that vibe coding hasn’t cost us something valuable—some share of the people that would’ve been good programmers in 1990, within a more passionate and principled culture, are rudderless without that culture to guide them, and this happens whenever a culture is diluted. The Eternal September is a mournful subject for a reason, after all.
I don’t think the causality is as clear or direct as you frame it, and I don’t think Dijkstra would agree with your framing either. I strongly expect it’s not about losing skills, but about never having the opportunity/requirement to gain the skills and knowledge (and never having to really internalize the lessons of the less-abstracted view).
I’ve been a professional programmer for a long time—starting well before there was the Internet. It was noticeably true in the late 80s that people who were incapable of writing and debugging assembly were not top-tier coders. It was true in the mid-90s that assembly was not the requirement, but C/C++ intricacy was a very good proxy for the mindset and attention to detail that made for good software. It wasn’t true by the mid-aughts—there were very good programmers in Java (but that sometimes included JVM bytecode debugging), and front-ends were getting complicated enough that it took real skill to be good at UI and apps. Throughout this “top tier coder” is doing a lot of work—there’s a HUGE amount of value from middle-tier coders, and that has increased over time as the abstractions have gotten better. This has led to a branching and specialization of what it means to be a “programmer”.
That branching matters a lot to this discussion. Once systems became fast enough and software infrastructure common/resilient enough, it made sense to have systems programmers be distinct from application developers, and then systems split into OS, compiler, platform, database, and application, and then further into middle-tier (“backend”) and user-flow (“frontend”), and has since specialized further.
It’s just impossible to say that one size fits all, even in terms of “how good a programmer” someone is. There are a bunch of different skillsets that matter at different layers, and it’s probably not possible for any one human to be good at all things. However, it does remain true that abstractions leak—to be great at any one thing requires a pretty deep knowledge and honed-through-experience instincts about the adjacent layers, and a shallower-but-still-real understanding more deeply.
Vibe Coding compresses this quite a bit—there’s a lot of layers that the controlling developer just doesn’t see, and that’s great until it breaks. It’s still the case that being able to actually line-level step through and debug things is necessary sometimes, and people who have ONLY vibe coded can’t do this (at least not efficiently/well—you need to do it hundreds of times before it’s natural). People who have done years of hand-coding CAN do this, even though it’s no longer very much of their energy (because vibe coding is so much more effective for 80% of things).
I’m not sure I have a point, other than there’s multiple dimensions here, and “able to do” is distinct from “does always”.
A couple of quotes that seem relevant:
Dijkstra, “The Humble Programmer”.
Eric Raymond, “How to become a Hacker”.
In times to come, perhaps we will have to replace “Lisp” by “any actual programming language at all”.
I don’t think level N skills cause you to lose level N-1 skills, but it might prevent you from gaining them. I also find that gaining N-1 skills help my performance at N skills (I think this is why universities usually teach multiple layers)
It feels annoying when teachers stress the importance of fundamentals to students who want to rush ahead to more “advanced” things, but the advanced things are composed of the fundamentals, and everything you do not understand the composition of becomes a sort of “black box” which harms your clarity, so the fundamentals are important.
However, the world is increasingly asking for skills of higher N, and the tower is getting quite tall, so it takes a lot of time to learn all the layers. And with every layer you go up, the task gets easier but less efficient. I’ve heard that the Windows 11 start menu is a React Native app, and I’m not sure if this is true but it wouldn’t surprise me.
People tend to consider the layer they grew up with to be superior, but the truth is that every layer is important (at some point, the highest layer so far becomes unmanagable without adding an additional layer). I don’t think LLMs are a layer here, for the same reason that “human programmer” doesn’t fit the hierarchy. And I think that they fail because the code they write scales poorly (bad architecture). The optimal structure in programming is fractal like, just like the optimal structure anywhere else. Tree → branches → leaves. CEO → managers → workers. Country → cities → houses. Program → classes → functions → lines.
That all said, I generally agree. I suggest not vibe coding at all.