Is AI producing donkey engineers?
The impression I have is that AI is turning out developers who can get code out of a tool but cannot judge it. What the basics used to be, and why they still decide who fixes the outage.
11 Sept 2026 · 4 min read · Leggi in italiano
The impression I have, and it stays an impression because I have no data to back it up, is that AI is producing a new category of developer. I have a name for it: donkey engineer. The definition is short. Someone who can get code out of a tool, but cannot judge what comes out.
This is not a category of incompetent people. They ship, they close tickets, and in many cases they move faster than someone with ten years behind them. The question is what happens when what the tool produced is wrong, because that is where you find out within ten minutes who understood what they shipped and who did not.
The alphabet that became optional
There are things that until three years ago were the bare minimum for anyone
writing React or React Native. The syntax of a useEffect and the reason the
dependency array exists. The fact that an effect which opens something has to
close it. The difference between useMemo, which runs what you hand it and
keeps the result, and useCallback, which runs nothing and keeps the function
itself, so that whoever receives it gets the same reference every render.
That is not a specialist subtlety, it is week one of React. These days you run
into people with years of claimed experience who will tell you that
useCallback and useMemo do more or less the same thing, and who cannot write
an effect with the correct syntax in front of an empty editor. Not because they
forgot it, but because they never had a reason to look inside, given that
something else has always written those lines for them.
What I mean by donkey engineer
The name is unkind and I know it. A donkey carries the load, it does not choose the route. The donkey engineer moves code from one place to another without deciding anything: prompt, output, paste, the test passes, next. As long as the route is the expected one, they get there before everyone else.
It does not apply to people who stopped writing code by hand but know exactly what they are reading. That is a different job, it is a legitimate one, and it is probably the job we are all heading towards. The difference is not how much code you type yourself, it is how much of it you understand when you read it.
The difference shows when something breaks
Generated code works almost every time. The problem is the almost. An app leaks a subscription when it goes to the background. A list redraws on every tap and the cheap phones start to heat up. A race condition only appears on a slow network, and only for users whose token is about to expire.
In those situations the model offers you three plausible fixes. All three are well written, and two of them are wrong. Choosing requires knowing how the thing works underneath, and no tool hands you that knowledge at the moment you need it. Either you already have it, or you spend the night trying alternatives until one of them stops throwing an error. Someone with the basics takes twenty minutes. Someone without them takes two days, and usually leaves another problem behind.
This is not an argument against AI
I work with an agent every day and I have no intention of going back. The direction is clear and it looks right to me: the value moves from writing the code to steering the thing that writes it, from typing to deciding what should be built and how.
Except that steering a tool means judging what it produces. If you cannot tell a
useMemo that is there out of habit from one that is saving an expensive
recomputation, you are not reviewing a diff, you are accepting it. If you do not
know why an effect needs a cleanup, the day your app starts leaking memory you
will not even have the vocabulary to state the problem. The model writes faster
than anyone, but whoever signs the pull request still owns what ships.
How you avoid it
Three things I keep doing, with no claim that they amount to a method.
I read the diff before accepting it, always, including when I am in a hurry and especially when I am in a hurry. If I do not understand a line, I stop on that line.
I ask the model why, not just what. I check the answer, because sometimes it is invented, but the question forces me to put the doubt into words instead of skipping it.
Every so often I write something by hand, no completion and no chat, with only the documentation open. Not out of discipline, but because it is the only way I know to measure how rusty I am getting.
AI replacing us is not what worries me most. What worries me more is a generation learning to produce without learning to understand, and all of us finding out on the day something large breaks and there is nobody left in the room who can explain why.


