So you’re getting ready to never again type out another line of code as you ascend to vibe heaven. I’m going to try to convince you that the fact that AI-assisted programming lets developers concentrate on higher level, more impactful tasks instead of wasting time actually writing the code has some drawbacks. I will try to do this without making you go “skill issue” and without you thinking I’m some kind of luddite.
Nowadays tech companies and developers in general are trying to add some constraints to AI-assisted programming to make it more predictable, require less iteration, produce safer and more maintainable code. This is great! That part makes sense. If you’re going to rely on these tools, you need structure.
In some teams this shows up as spec-first workflows: you describe behavior, edge cases, and constraints along with the agent, then ask an agent to implement against that description.
In many of these workflows, the developer’s role shifts away from implementation almost entirely. You make sure that the documentation that describes the feature is correct, and then review the code that the agent generated based on the documentation. You might even delegate review or at least complement it with another agent that compares the documentation with the actual changes. The code itself arrives finished.
From a productivity standpoint this is undeniably effective, but it also changes how you relate to the system.
The main point I believe in and want to get across is that people get better at systems by implementing them. Not by typing for the sake of typing, but by being forced to make decisions: where boundaries go, how control flows, what names mean, which invariants actually hold. A lot of understanding only shows up when you’re the one committing to a structure and living with it.
That kind of understanding is hard to recreate later by reviewing generated code. Writing and reviewing are not the same activity. Reviewing checks correctness and consistency, while writing forces you to think.
There’s a very reasonable counterpoint to all of this. For experienced engineers, much of the real work happens before any code is written. The value is in judgment: understanding trade-offs, sequencing changes, anticipating failure modes, and managing risk. From that perspective, typing code is mostly follow-through, and delegating it to an agent is an obvious win.
I get that view and I even agree with parts of it. Better tools let us push more thinking upstream, and that’s a real improvement.
Where I’m less convinced is in treating hands-on programming as optional. Some insights still only appear during implementation. Some designs only reveal their problems when you try to express them precisely. And some intuition only stays sharp if you keep exercising it.
None of this is an argument against using agents. The boring parts of programming — boilerplate, mechanical refactors, glue code — are perfect candidates for delegation.
What worries me is how quickly we’re normalizing the idea that all programming should be delegated. That engineers should think only in terms of outcomes, and treat code as an implementation detail best handled by something else.
Here’s the thing: I actually like programming. Adding a feature, fixing a subtle bug, or realizing halfway through that a design can be simpler than you thought is still valuable work. Not just because it feels good, but because it builds understanding.
There’s probably a middle ground here. Let agents accelerate the work. Let them handle the boring and mechanical tasks. But still choose, deliberately, to write real code in places that matter, even if that makes us a bit slower.
Yes, there’s some nostalgia in that. That’s fine. We’re human, not throughput optimizers. Enjoyment, intuition, and long-term sharpness count for something too.