Some Thoughts on Vibe Coding (1)

Prequel · I

On 30 November 2022, OpenAI released ChatGPT. Eight days later, in my student flat in Preston, I got an interview invitation for a data-analyst job. I opened it up and sent my very first message to GPT-3.5:

My very first message to GPT-3.5, late 2022 — What should I say to pass a statistical analysis job interview?
My first message to GPT-3.5

What word would even fit how I felt? Joy? Shock? Or fear?

I was like a caveman seeing fire for the first time — no idea how to keep it lit, couldn't think of much use for it beyond cooking, but dead certain about one thing: this was the future.

Twelve days later, I got the offer.

Prequel · II

On 14 March 2023, barely three months into my new job, GPT-4 was released.

What truly shocked me about it wasn't how much smarter it was than GPT-3.5, but that it was the first multimodal model — the first that could understand images. Until then, my daily work meant staring at one usage curve after another, slowly working out why some household's electricity consumption looked abnormal, then writing it up into a report word by word — and even that wasn't the end of it: I still had to run it through Grammarly to straighten out the grammar before I dared send it to a client. From that day on, all I needed was a screenshot and the simplest possible prompt, and it would hand me back an analysis detailed almost to the point of excess, without a single grammar mistake to be found.

It was as if I watched, with my own eyes, a mushroom cloud rise right in front of me — I slumped at my desk and took a good while to recover.

Prequel · III

On 5 January 2026, I dug up some old videos I'd posted years ago and found they barely played on modern devices anymore: frames combed through with interlacing artifacts, some with audio that wouldn't decode at all. I wanted to re-encode them, went looking for a tool, and found there were simply no good options: the all-in-one converter suites come stuffed with bundled software and ads, while FFmpeg — clean as it is — has no GUI and might as well be hieroglyphics to an ordinary person; try tweaking parameters or batch-converting, and it gets painfully inefficient.

So I thought: why not just build one myself?

A year earlier, a thought like that would have flickered and gone — I couldn't write code. But this time I threw the idea at Claude Opus 4.5. And it one-shot the entire piece of software, more or less.

If GPT-3.5 was the first time I saw fire, and GPT-4 was watching that fire rise into a mushroom cloud in front of me, then this was the first time I realized: I could make fire myself, and forge my own tools. That's how my programming journey began (the result lives here: NextGen Hyperspeed Video Converter).

The main story · I used the fire, but never learned to make it

After that, I dove headfirst into what people call vibe coding: hand the requirement to the AI, it lays the code out, I give it a quick once-over, nothing looks wrong, Approve; the page runs, the feature works, and everything goes more smoothly than I had any right to expect.

It took me about two or three weeks to realize one thing: in all that time, I had remembered almost nothing. That function the AI wrote for me yesterday — ask me today to just write it again myself, and I couldn't produce a single line. It's not that I "forgot the details" — it's that it never left a trace in my head in the first place. The code sits in "my" project, but that logic never truly entered my brain.

The fire, I did get to use; but making fire itself, I don't seem to have learned. That left me somewhat uneasy, so I went searching: where exactly does this go wrong?

1. Hitting Approve is recognition, not generation

There's a very old result in psychology called the generation effect: people remember what they produce with their own hands far better than what they merely read or recognize. And the daily routine of vibe coding sits entirely on the "recognize" side: the AI generates the code, I skim it, it looks fine, I hit Approve — from start to finish, not one step of it is producing anything with my own hands. The brain never does any work, so of course nothing stays.

There's a companion result called "retrieval practice," also known as the testing effect: memory gets consolidated in the effortful act of pulling an answer back out of your own head — the harder the recall, the firmer it sets. And what the AI does is precisely to lay the answer right in front of you — even the "pulling out" step is skipped, so the "consolidating" naturally never happens either.

Once I'd worked this through, I actually felt relieved: it's not that I got dumber; it's that I skipped, in its entirety, the very step that builds long-term memory.

2. "People trained the old way are just better" — we've been saying this for seventy years

My second thought was: could it be that the older generation of programmers is simply better than mine? They were, after all, trained the "old-school" way.

Then I looked into it and found that this idea has been repeating for at least seventy years — nearly every generation of programmers has been convinced of the same thing: that the next layer of abstraction will make people soft. When FORTRAN first appeared, plenty of people looked down on it because "hand-written assembly is more efficient," and the first high-level language was for a while treated as a tool for the lazy; the 1983 satire Real Programmers Don't Use Pascal poked fun at the assembly fundamentalists' creed — "if it can't be done in assembly, it isn't worth doing" — and in their eyes even structured programming counted as academic self-indulgence; later still, it was the C programmers' turn to look down on Java and Python. Round and round it goes.

The interesting part is that every new layer of abstraction, at the moment of its arrival, gets denounced as "cheating" by the layer below — yet in hindsight, every move up in abstraction ended up making the industry bigger and programmers more numerous, not fewer (for the full arc, see the history of programming languages). So the "old-timers were just built different" sentiment is probably just a line that's been said for seventy years — and now it's simply my turn to say it.

3. The old-timers were built different because they had to be

So what actually made the old-timers built different? My answer now: not talent, but an environment that left them no other choice.

Writing frontend used to mean knowing this by heart:

JavaScript
document.querySelector("#btn").addEventListener("click", function () {
  console.log("clicked");
});

Writing backend meant having this straight in your own head:

JavaScript
app.get("/users", async (req, res) => {
  const users = await db.user.findMany();
  res.json(users);
});

Writing SQL meant being able to produce this on the spot:

SQL
SELECT * FROM users WHERE email = 'test@example.com';

Writing React meant genuinely understanding what this line means:

JavaScript
const [count, setCount] = useState(0);

These look like mere syntax, but underneath every line sits a whole stack of concepts: What is the DOM? What is an event listener? What are a request and a response? What is async / await? When state changes, why does the page re-render by itself? And what exactly is the relationship between a database query and a backend endpoint? The AI can hand you the code directly, but it won't put those concepts into your head along the way. Without the rounds of typing, running, and debugging things with your own hands, the brain never grows that stable structure.

4. Why you feel like "I can't learn the syntax no matter what"

If you're learning to code right now and your head is full of "I can't even learn the syntax," here's what I'd say: the problem is most likely not the syntax itself, but one of the three gaps below.

Gap 1: the input is too high-level, the output too complete

You tell the AI: "Build me a login page, wired to a backend API, with login authentication." It promptly hands you the full set: a React component, form state, the fetch request, token storage, routing, error handling, the backend endpoint, middleware, the database query. For a beginner, that information density is simply indigestible — in front of you is a complete system, but you haven't yet climbed, rung by rung, the ladder of

variables → functions → objects → async → HTTP → components → state → database → auth

So you arrive at the conclusion that "I can't even learn the syntax." But this really isn't a syntax problem — the abstraction level just jumped too fast.

Gap 2: AI spared you the process of getting it wrong

Why did the old programmers remember things so well? Because they went through this loop over and over: write it wrong → error → dig through the docs → fix it → another error → dig again → finally it runs. Say your hand slips and you write:

JavaScript
const name = "Jack";
name = "Tom";

and run straight into:

Output
TypeError: Assignment to constant variable.

After that happens once, you'll likely never forget, for the rest of your life, that const can't be reassigned. But if the AI places the correct code straight into your hands, you have only ever "seen" it, never "gotten it wrong" — and having seen something and knowing it are two different things.

Gap 3: modern frontend and backend really are far more complex than they used to be

If you feel like "why is there so much to learn in frontend and backend now," that feeling isn't an exaggeration; it's real. Frontend stopped being the HTML / CSS / JS trio long ago: frameworks (React / Vue / Svelte), Node.js, package managers (npm / pnpm), build tools (Vite / Webpack), REST / GraphQL, state management, routing, auth, deployment, CI/CD — layer stacked on layer; and backend isn't a few endpoints and done, either: the language, frameworks, databases, ORMs, caching, queues, auth, logging, error handling, testing, containers, cloud services, security, performance… an equally long list. So it's not that you can't learn it — it's that you walked in and found yourself standing at the foot of a tech stack that has been swelling for decades. And don't forget: those "old-school programmers" climbed it one layer at a time too — no one ever learned React, Next.js, PostgreSQL, Docker, Kubernetes, Python, and Rust in a single day.

Back then, no one had to climb the whole mountain alone, either: a frontend developer could go an entire career without touching a database, a backend developer could get by without ever knowing what imperative versus declarative UI even means, and one or two languages, mastered well, could carry a working life. In the AI era it's flipped — since you can build everything yourself, you end up facing everything yourself: frontend, backend, database, deployment, all on one pair of shoulders. The mountain didn't get any shorter; it's just that instead of each of us climbing our own stretch, one person now climbs it top to bottom.

5. Taking a real piece of code apart

Say you ask the AI for a login feature. It might hand you this:

JavaScript
const response = await fetch("/api/login", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email, password }),
});

const data = await response.json();
localStorage.setItem("token", data.token);

If you don't have much of a foundation, these few short lines throw a whole string of questions at you at once: What's const? What's await? What's fetch? What are headers? What's JSON.stringify? Why does response.json() need another await? What's localStorage? And what is a token anyway, and why does it have to be stored? You think you "don't understand JavaScript syntax," when in fact you're facing six things at the same moment: variable declaration, asynchronous programming, the HTTP protocol, JSON encoding, browser storage, and login auth. Finding it hard is the normal outcome.

The more sensible approach is one layer at a time. Layer one, just variables:

JavaScript
const email = "jack@example.com";
const password = "123456";

Layer two, objects:

JavaScript
const user = {
  email: "jack@example.com",
  password: "123456",
};

Layer three, functions:

JavaScript
function login(user) {
  console.log(user.email);
}

Layer four, async:

JavaScript
async function login() {
  const response = await fetch("/api/login");
}

Only at layer five does the full login flow get its turn.

6. Being able to write code doesn't matter anymore

At the end of all this, what I actually want to say is: today, "being able to write code" — the thing itself — probably doesn't matter anymore. Syntax, APIs, boilerplate — the IDE completes it, the docs have it, the AI writes it faster and better than almost anyone. So if you keep feeling like you "can't even remember the syntax," hold off on concluding that you're not cut out for this: the part you can't remember is precisely the part that lost its value first.

What actually matters has moved outside the code: whether you have taste — whether you can tell what's genuinely good from what merely gets by; whether you understand real pain points, and know what's actually blocking people; whether you can take a vague idea and state it clearly enough that an AI — or any person — knows exactly what to do; whether you know how to direct your tools, when to rephrase the question and when to throw the attempt away and start over; and once the thing is built, whether you can stand on the user's side and judge whether it's actually good to use. And one more, the easiest to overlook: whether you can notice that "this is something I can do now" — plenty of things stay unbuilt not because they can't be built, but because nobody has caught on that they already can be.

So, what has vibe coding actually done to me? By this point the answer is clear: it didn't make me dumber — it just crashed the price of "being able to write code" through the floor. That stretch of panic, frankly, was me failing to catch up with reality: I was anxious about a depreciating skill, like someone who's just been handed a lighter and still feels bad about never learning to start a fire with sticks.

It took humanity hundreds of thousands of years to learn to make fire, and a few thousand more to turn fire-making into a triviality; from fire as a triviality to a mushroom cloud capable of ending us all took about a hundred years.

About this post

AI-generated content
No
AI-proofread content
Yes (Model: Claude Fable 5)
AI-translated content
Yes (Model: Claude Fable 5)
Share