# Artificial Intelligence Won't Replace Programmers

How LLMs shift engineering bottlenecks from writing repetitive syntax to system architecture, security boundaries, and debugging.

Published 2026-01-04, updated 2026-09-24 · https://wrksz.dev/en/blog/ai-wont-replace-programmers

---

Before tools like [ChatGPT](https://chatgpt.com/) launched in late 2022, writing a standard backend meant a lot of boilerplate. Frameworks handled routing and connections, but you still wrote models, serialisation logic and validation schemas by hand, and most of that work was mechanical.

LLMs turned that work into a commodity. They are not [AGI](https://en.wikipedia.org/wiki/Artificial_general_intelligence) and they do not reason through novel business problems on their own, as examples like this one show:

[https://x.com/arm1st1ce/status/1964327067173958021](https://x.com/arm1st1ce/status/1964327067173958021)

Trained on millions of public repositories, issue trackers and technical discussions, they do reproduce standard code patterns reliably: project structures, database queries, test suites. Once generating syntax got cheap, developer time moved from typing code to directing models.

So the useful question is which workflows actually gain from generation, and where uncritical vibecoding turns into a liability.

## Where unchecked generation fails

An application built entirely through prompts, by someone who does not understand the code, usually runs fine until real users arrive. Then unverified dependencies and exposed environment variables turn into data breaches. The [Tea app leak](https://www.bbc.com/news/articles/ce87rer52k3o), which exposed government ID scans and user data, shows how that ends.

> [!CAUTION]
> A language model does not own production outages, technical debt or multi-tenant isolation. It generates a completion and moves on.

## The bottleneck moved to system design

Code generation is fast, so the slow part is now architecture, data flow, trust boundaries and operational cost. Clean syntax from an LLM does not guarantee that two systems integrate safely, or that a query survives past a hundred-row table.

Vibecoding speeds up engineers who already understand those constraints. Used instead of understanding them, it produces technical debt faster than any team could by hand.

## What vibecoding actually is

The term vibecoding comes from [Andrej Karpathy](https://en.wikipedia.org/wiki/Andrej_Karpathy), who described it in February 2025 as a workflow where you "fully give in to the vibes, embrace exponentials, and forget that the code even exists", talking to the editor instead of typing:

> I "Accept All" always, I don't read the diffs anymore. When I get error messages I just copy paste them in with no comment, usually that fixes it. The code grows beyond my usual comprehension, I'd have to really read through it for a while.

Andrej Karpathy, [on X, February 2025](https://x.com/karpathy/status/1886192184808149383)

Karpathy meant it for throwaway weekend projects. In practice it split into a spectrum, from handing over a whole application to deliberate acceleration, where you still write the requirements, read the diffs and set the architecture while the model types the repetitive parts. That kind of use is not free, either: \$30 per million input tokens and \$180 per million output tokens for [GPT-5.5 Pro](https://developers.openai.com/api/docs/pricing).

Tools like [Claude Code](https://claude.com/product/claude-code) and [Cursor](https://cursor.com) work well while the model assists your implementation. The trouble starts when it replaces your judgement.

## Three levels of use

What separates productive use from dangerous use is whether anyone understands the generated system:

| Level                 | The diffs                  | If the model disappeared tomorrow              |
| :-------------------- | :------------------------- | :--------------------------------------------- |
| Controlled assistance | you read every one         | you slow down, the architecture is still yours |
| Passive acceptance    | merged once the tests pass | nobody can explain parts of the system         |
| Total delegation      | nobody reads them          | nobody understands the code at all             |

### Controlled assistance

You understand every file the model touches. You check the generated code and its test coverage, and you step through edge cases in a debugger. The prompt is a shortcut for code you could write yourself. This is how I use Cursor Pro day to day.

### Passive acceptance

Convenience starts to erode quality. You still know the fundamentals, but you stop reading every diff; if the tests pass locally and the server boots, it gets committed. Refactoring and security audits get pushed back, and the project looks fast until edge cases show up that the team can only explain by asking the model to interpret its own output.

### Total delegation

![You wouldn't vibecode a banking app](https://wrksz.dev/images/blog/vibecoding.png "Full vibecoding looks fast until the first real user, or the first attacker, shows up.")

The whole stack goes to agents and prompt-based platforms like [v0.dev](https://v0.dev), [Bolt](https://bolt.new) and [Lovable](https://lovable.dev): frontend, database schema, authentication, infrastructure, none of it inspected. Within hours there is a working interface with CRUD endpoints. Then agent subscriptions and token costs pile up, and the codebase stays an opaque pile of unvetted dependencies.

## The good sides of vibecoding

The best part might not be yours. Pentesters wait for apps like this. Relax, you will pay them anyway. Or you won't.

Often nobody files a report at all. What breaks first is usually mundane: an endpoint someone assumed was internal, with no role check, so any user can pull anyone else's records, sometimes all of them at once. The people who find it do not want a bug bounty. They want the data, and you find out when you wake up to a dumped database.

> [!NOTE]
> Private projects are still fair use: small tools and automation scripts nobody else touches. Prototypes too, when you want to know in one evening instead of a week whether an idea works.

Vibecoding is fine while the only person you can hurt is you (unless you are ~~a real man who can handle the leak~~ an egoist who doesn't care that other people's data is pouring out of your app).

## Learning with generative tools

If you are learning to code, leaning entirely on generation stunts you. Watching a model produce working output skips the part where you break the problem down yourself.

That part is the job: understanding how state changes, where network requests fail, why one data structure fits a workload better than another. Chasing a failing test, an off-by-one error or a compiler diagnostic builds the mental model you need to judge production code, and without it you cannot fix the system on the day the model gets it wrong.

## Which developers are vulnerable

Language models will not eliminate engineering roles. They will replace work that is only repetitive syntax with no architectural understanding behind it, and developers who live on templates or hand all their debugging to tools will find their output easy to match.

Although... maybe it replaces me too? And you? I have a plan: shrimp farm. You?
