3966 stories
·
4 followers

We are all Product Engineers now

1 Share

Just yesterday I published a very long post about the economics of open source. As part of that argument, I mentioned that the cost of writing software has collapsed, and that meant the variables in the equation had changed for the first time in thirty years.

That led me off on a tangent that grew into this equally long post. I had a bunch of questions to answer. Has the cost of creating software really collapsed? Can I prove that? If the cost of actually producing code goes to zero, what parts of the job of “software developer” really remain? Where, in fact, is the entire industry of software going in the next decade?

You can see why I felt it needed a post of its own.

I’ve been circling this topic for a while now. In early 2025 I predicted AI would create many more programmers and that their jobs would look different, but I didn’t get into the details of how different, and also that was more than a year ago, an infinity in the compressed timeline of AI. In March this year I found companies substituting compute for labor at record rates. In July I looked into labor statistics and found that the market for junior programmers had been savaged while the market for senior ones was fine, in fact growing.

This post is an attempt to build on those and make a forecast of where the industry is going in the next 10 years. Making a 10 year forecast of anything is of course a crazy thing to try to do, and especially about the business of software right now. To make it, I had to make two very big assumptions.

Assumption 1: agents are going to eat the entire software development lifecycle

This assumption is based on the observation that agents are currently very good at writing code and mediocre at everything that comes after that: reviewing code, testing it, finding bugs, fixing bugs, deploying to production, monitoring, and scaling up. They suck at that stuff right now, but my assumption is that that’s a temporary state of affairs. There’s nothing structural about those things that prevents agents figuring out how to do that stuff. If you think I’m right about that, this post will be of interest, but if you think I’m wrong now is a good time to bail.

Assumption 2: there is no upper bound to how much software we need

This one is if anything even more out on a limb. If you think I’m wrong about this you probably think software developers as a profession are doomed. I disagree.

I've made this argument before: look at the website of your dentist, your insurance company, your kid's school, or literally any department of any government, and you're looking at software that is terrible not because nobody knows how to build better software, but because the people who need it can't afford to pay for better at current prices. Then think about all the things software hasn't touched at all, which is most things. Every small business runs on a spreadsheet and a group chat and a person who remembers stuff.

That means there isn’t now and isn’t going to be a glut of software developers, and anything that looks like one right now is a temporary transitional state. The demand for software, at least inside my 10 year horizon, is for practical purposes infinite, or software developers wouldn’t be as highly paid as they are.

But the job of a “programmer” is about to get very, very different. So different that you might not even recognize it as “programming” any more, while still being recognizably “software development”.

The job of making software will become what the agents can’t do

If agents are going to eat the entire software development life cycle, what does that leave behind?

To figure that out, I broke the cost of making software into as many component pieces as I could think of. I came up with a long list, in four categories:

Collapsed:

  • Actually writing code: historically the most expensive part of the whole process, because getting it right was really tricky. The entire industry oriented itself around very expensive programmers as the center of gravity, with every other job more or less orbiting around them. The cost of this, with LLMs, has already collapsed.

Going soon:

  • Reviewing code: I’ve written about the death of the code review before, the TLDR being: it hasn’t happened yet, but it looks like it’s about to.
  • Maintaining code: finding bugs, fixing bugs, refactoring. Agents are making real progress here but are still not great.

Next on the chopping block:

  • Shipping code to production: getting it out of dev onto real production hardware. With various platforms this has been dropping for a while, and my assumption is that agents are about to get very good at it.
  • Scaling up: not something I’ve seen anyone talk about, this is a big part of successful software development. I’ve not seen people throwing agents at production bottlenecks so far.

Possibly safe:

  • Deciding what to build in the first place: figuring out what the customer actually wants is a huge part of software development, and so far I haven’t seen anyone throw an agent at it. To my mind, this is the most durable part of the job.
  • Deciding the definition of “good”: this is the intersection with my day job in the world of AI evaluation. I’ve not seen any attempts to automate this. How would you even know, short of asking a human, what good looks like?
  • Making it delightful: we can all tell the difference between a piece of software that gets the job done and one that’s actually easy and fun to use. Can an agent? The current state of agentic design does not suggest that they can, but this one is the most wobbly of the three.

Then there’s a bunch of things that are arguably not software development at all, but are still part of the software industry: marketing, user acquisition, retention, branding. Who knows what agents can do with them, but I’m not considering them.

All juniors did was write the code you told them to, and that’s gone

I already talked about this in my post about the labor market, so I won’t reiterate the whole argument. The thing agents got good at first was producing code from a description, which is exactly the thing junior developers were hired to do. It was the whole point of hiring a junior: you gave them a well-specified ticket, they produced mediocre code, a senior reviewed it, and over about a decade of that they absorbed enough judgment to become the senior.

The problem from that post is: if you don’t need juniors to handle well-specified tickets any more, where do the seniors come from? We have to train them in a different kind of job. The point of this post is: what job?

Since July the Stanford team has updated their numbers and things did not improve for junior developers. The employment gap for 22-to-25-year-olds in AI-exposed jobs is now 19% below where it would be if they'd tracked their less exposed peers, up from 15% a year ago, and it's happening through reduced hiring rather than layoffs. More interesting is where it's happening: young workers lost ground in occupations built on knowledge that's been written down somewhere, and experienced workers gained ground in occupations built on knowledge you get by doing the job. The Stanford authors call these codified and tacit knowledge, and I'd call them "stuff that's in the training data" and "stuff that isn't", but it's the same distinction, and it maps exactly onto "what juniors do" and "what seniors do." SignalFire's 2026 talent report has the corporate side: entry-level hiring at the big tech companies is down 65% since 2019, at early-stage startups it's down 75%, and yet engineering as a share of hiring went up, from 46% to 55%.

Companies are hiring fewer people overall, but a bigger share of the people they do hire are engineers, just not the kind whose primary job is typing code.

Going soon: reviewing and maintenance

For reviewing and maintenance, agents are clearly not there yet, but the data shows them on an upward trajectory.

On benchmarks where agents fix real bugs in real repositories, frontier models went from roughly 50% to roughly 95% in the last two years, to the point where the main benchmark is effectively saturated and people have had to build harder ones. On the harder ones, which resist the models having seen the answers during training, the best models now score around 59%. That’s not good enough, but neither was 50% two years ago and that went away really quickly.

A study of 567 pull requests opened by Claude Code across 157 open source projects found 84% of them eventually got merged, a bit below the human rate of 91%, and just over half went in without a human touching them. Google's Big Sleep agent found a memory corruption bug in SQLite that traditional fuzzers had missed and that attackers already knew about, and has found around twenty more since in things like FFmpeg and ImageMagick.

Until they do, the ability to create code but not to review it is causing an enormous amount of pain. GitHub added 36 million developers and a quarter more commits in a year, and the number of merged pull requests on the platform is up something like three and a half times since 2023, with one estimate having agents alone opening 17 million PRs a month. Something should review all of that, but one study of 33,000 agent PRs found that most PRs on GitHub, human or agent, get no recorded review at all, and when agent PRs are reviewed, 58% of the time the only reviewer is another agent. In open source, examples abound of projects shutting out new submissions because of a tide of AI slop and the inability to effectively review them; curl shut down its bug bounty in January after the share of submitted reports that were real bugs fell from better than 15% to under 5%.

Next on the chopping block: operations and scaling

For this part of my argument data was really thin on the ground, so I’m relying heavily on my “looks like it’s going to happen” assumption from the start. There are some benchmarks that look more like operating a system than fixing a bug, and agents are somewhere under 65% on them. This isn’t a thing happening yet, which is why there’s almost no data either way. It’s just the thing that, logically, looks like it’s next.

What's left is finding out what people actually want, and only they know

So if the code is free and the operations are free, what’s left? It’s sometimes called "product sense", and it’s highly valued in senior developers, but what does that mean exactly?

At some point every piece of software is a formalization of a human desire. Somebody wanted something, and the software is a precise enough statement of that want that a computer can act on it. When a customer says "I need to keep track of my orders," there are ten thousand pieces of software that fit that sentence, and only one of them is right for a bakery, and it's a different one from the one that's right for a car parts factory, and the only person on earth who knows that the customer is running a bakery and not a parts manufacturer is the customer.

You cannot do product discovery mechanically short of reading people’s thoughts. You can't train it into a model, because it isn't in the training data, because it's in the head of one specific baker who's never written it down and wouldn't know how to if you asked them. Somebody has to go and get it out of her, and then turn it into something exact enough to build, and then check that what got built is actually what she meant, which it never is the first time.

There is no economy of scale in product decisions

The cost of deciding what the customer wants has a very important property: it doesn't transfer well. The definition of "good" for a calendar app and the definition of "good" for a scheduling app, which are two ways of solving roughly the same problem, have almost nothing in common, and two bakeries don't have exactly the same problem either. Whenever you see software with a zillion configuration options that still doesn’t do what you need it to do, you’re feeling this problem. It’s why software so often sucks, and why I say the demand for good software goes to infinity. Software requirements are more different than we’ve been able to admit while we’re still trying to write one-size-fits-all software.

As the cost of software creation falls to zero, the bottleneck moves to the description of the problem, and my thesis is that’s where it’s going to stay.

What about design?

I'd separate out design from this, because it's related but it's not the same thing. Design is the part where two solutions both correctly solve the problem and one of them is the one people actually like using. Everybody who's watched a well-specified product lose to a nicer one knows this is real, and I can't quantify it, and I'm suspicious of anyone who says they can. But I'll note that it has the same structure as the description cost: it's per product, it doesn't transfer, and cheap code makes it more important because when everyone can build the correct thing, the nice thing is what's left to compete on.

The job that remains is called Product Engineering

So what does that leave behind? Let’s talk history for a little bit.

When computers were new and programmers were scarce and expensive, companies hired a person whose entire job was to sit between the business and the programmers, understand what the business needed, and write it down precisely enough that a programmer could build it without talking to anyone. This person was called a systems analyst. There's a 1963 memo from Miami University describing systems analysis as a brand new profession born out of the mountain of paperwork business executives faced: it was the translation layer, created because the people who could type were too valuable to also do the talking (and also, people who were very good at laying down code seemed to be not very good at talking to humans anyway).

Then software went commercial and, especially, consumer-facing, and the translation job changed shape. Consumers don't want to sit in requirements meetings: they just want to be handed a thing they like. So the person whose job was understanding what people wanted stopped being an analyst who interviewed the business and became a product manager who studied the market, a role borrowed more or less directly from Procter & Gamble's brand managers by way of Intuit and then Microsoft, where a programmer named Jabe Blumenthal invented "program manager" in the late 1980s because Excel for the Mac needed somebody to own what it should do.

The function moved into Product, and Product got separated from engineering as a career, and for the last twenty-five years we've had two professions where there used to be one and a half. I bring this up because it means the job I'm describing isn't a speculative new thing that we'd have to invent. It's a thing we've had for sixty years under two names. My speculation is that it’s about to collapse back into one job.

The new job is already being hired for, under a dozen names

You can see the start of this change arriving now: it’s showing up as job postings for a role nobody had heard of three years ago.

Palantir coined "forward deployed engineer" for a person who goes and sits with the customer, figures out what they actually need, and builds it, inside the customer's environment, with the customer watching. It was a Palantir oddity. Then in 2025 postings for it grew by something like eight hundred percent in nine months, and by this month a census counted almost a thousand live postings across 462 companies, including OpenAI, Anthropic, Databricks, Stripe and Google Cloud, with Salesforce saying it wants a thousand of them to roll out its agent products. The average total comp is around $240,000 and senior ones clear $600,000, which is to say it pays like a senior engineer, because it is one. The same role is being posted as solutions engineer, deployment engineer, applied AI engineer, implementation engineer, and half a dozen other things, because nobody has agreed on the name yet, because it’s so new that nobody has standardized it yet.

But read the job descriptions and you see, roughly, a senior product engineer. The responsibilities include: scope the problem with the customer, understand their business, write production code into systems you didn't build, iterate with them until it works. The code-writing is in there, but it's the smallest part, and it's the part the agent does; what the company is paying $240,000 for is the person who can walk into a car parts factory and come out with a correct definition of "good." The market has already decided this job is incredibly valuable.

But that’s not programming!

Here’s the part that’s going to suck for a lot of people who develop software currently: no, this isn’t programming. It’s recognizably still software development, but laying down code is a vanishingly small part of it and, if the trends I’ve laid out here are real, going to get even smaller.

I want to be careful here because “figure out what to build, not how to build it” is also a description of the part of software development I personally always liked, and there's a well-known failure mode where everyone with an opinion about AI concludes that all jobs will be automated except theirs, which is mysteriously impossible to automate. So take this with the appropriate salt: I think the durable, paid part of making software becomes the part where you understand a problem better than the customer does and think harder about the solution than they can, and I think that's durable because it can't be extracted from the customer mechanically, and I think it's paid because if you don’t do it you get software that everyone agrees sucks, which is to say: most current software.

The market wants context and taste and nobody is being trained for those

Here's where my forecast runs into a problem.

The input the software development industry is about to need in unlimited quantities is people who can extract requirements from humans, define good, and exercise taste, and we do not make those people. Product people fall into their jobs by accident, as a byproduct of the typing job, or sometimes a marketing job, or maybe a consulting job. For developers, you hired a junior to write code, a senior reviewed it, and over a decade the junior picked up judgment by osmosis. That's how every senior engineer I know got their taste, and it's the loop I said in July is now broken, and it's broken because the first rung on the ladder was "type code somebody else reviews" and the agents are going to do both of those things.

Formalized training of product people barely exists. Google's APM program, which Marissa Mayer started in 2002 and which is the template everyone copies, takes about fifty people a year out of something like twelve thousand applicants. Meta, Uber, LinkedIn, Salesforce and a few others run equivalents of similar size. Add them all up and you get maybe a few hundred people a year trained, on purpose, to do the thing I'm claiming is about to be the whole job, against a junior developer pipeline that used to be tens of thousands and is now on fire. Universities teach data structures. Bootcamps teach React. Nobody teaches "go sit with a baker for a week and come back with a spec," and the pipeline for turning junior devs into that role by accident has been closed, also by accident.

The market wants people with context and taste and we are simply not training those. We’re not even sure we know how. Until that changes, the scarce input stays scarce, the people who have it get more expensive, and most of the world’s software stays bad for longer than it needs to.

I do think the market will probably solve for this. The price of the scarce thing goes up until somebody finds it worthwhile to make more of it. IBM is already redesigning its entry-level role around customer contact and specification instead of typing. Companies paying $240,000 for forward deployed engineers will eventually notice it's cheaper to grow them, and universities will eventually notice that "requirements analysis" is a course people would pay for, but it will all happen too slowly, and a cohort of people will get hurt in the meantime, and I'll come back to them. But the demand is real and the demand is what fixes it – eventually.

The craft as paid work is mostly dead, and that is a real loss

I’ve posted this sentiment before, but it’s a real tragedy that shouldn’t be glossed over. I've seen a lot of despair from career programmers over the last two years and I don't think the right response to it is a chart showing that aggregate employment is going to be fine.

A lot of people got into programming because they love the craft of it. The feeling of a clean abstraction. The satisfaction of a hard bug finally yielding. The specific pleasure of making a machine do exactly what you told it, which is a pleasure most jobs don't offer. Those people did not sign up to interview bakers. Some of them have no interest in product management and some of them are actively bad at it, in the way that some brilliant engineers are, and they're looking at the forecast I've just written and seeing their job turn into a job they'd never have chosen.

I think they're right, and I don't have a consolation prize. The craft of writing code as a thing somebody pays you to do is, I think, mostly over, outside of niches that will get narrower every year. That's a real loss and it's a loss for the profession as well as for the people, because the craft is where a lot of the taste I've been talking about actually came from, and we're about to find out what taste looks like when nobody grew up doing the thing.

Two things I'd say that aren't consolation, just observations. One is that for a fair number of the people who think they loved the typing, the part they actually loved was the moment before the typing, when a vague mess of a problem resolved into a precise shape in their head. That moment is the job now. If that's what you loved, you're going to be fine and possibly better than fine, because the industry is about to be desperate for you. The other is that the craft survives, the way woodworking survived the furniture factory, as a thing people do because they love it and occasionally get paid a premium for. Developers write software the way singers sing. That was true when it was free and it'll be true when it's automated, and the people who love it will keep doing it, and some of the best software will keep coming from them. It just won't be the job.

Ten years of turmoil lie ahead

It’s been a long 4000 words, so let’s review.

The cost of writing code collapsed, and the cost of reviewing, fixing and operating it is following, and I'm assuming it gets there. What's left of making software is finding out what people actually want, defining it precisely, and making it pleasant to use. That cost is per piece of software and doesn't transfer, so as the amount of software goes to infinity, which it will because there's no ceiling on demand, that cost becomes the whole job.

That job is called a product engineer. It's being hired for right now under a dozen new names at senior engineer pay. And the training pipeline for it is roughly fifty people a year at Google, because the way we used to produce it was as a side effect of a typing job that no longer exists.

I think the next ten years are going to be ugly, because the load is arriving before the tools do, the junior ladder is gone before the replacement exists, and a lot of people who loved the craft are going to have to decide whether they love the job that's replacing it. I think by ten years it shakes out, the way it did when compilers and then frameworks and then open source each made a generation’s worth of typing unnecessary, into a profession that is larger than today's, pays about as well, and is mostly shaped like product engineering. At twenty years I have no idea; if we hit anything resembling general intelligence in that window then this post and every other post about jobs is moot. But for the horizon I can see, the forecast is: more software, more people making it, and almost none of them typing. We are all product engineers now, whether we like it or not, and a lot of us won't.

Read the whole story
emrox
33 minutes ago
reply
Hamburg, Germany
Share this story
Delete

Faster previews, soon powered by OJ

1 Share

A Lovable preview is not a static page. It is a real developer server running your real app, with hot reloading. That means it keeps the app running and sends your browser new versions of the files you edited on the fly. Under the hood the engine to make this work has been Vite, which is the modern industry standard.

The catch is not that Vite does anything wrong; it is built for one developer on one laptop. Lovable is a different problem: we run around a million sandboxes a day, one preview each, spinning them up and tearing them down constantly, and at that scale the resources each one holds are what matter.

Each Vite instance brings a JavaScript runtime, installs a toolchain into the project, and holds a lot of memory. Across thousands of previews that adds up to slower cold starts when you open an app and a heavier footprint for every sandbox we keep warm.

We wanted previews that start instantly and stay light, without giving up the ecosystem that makes the app work in the first place.

What OJ is

OJ (internally nicknamed Orange Juice) is a single Rust binary that runs your app the way Vite does. It reads your existing vite.config.ts (or oj.config.ts), runs real Vite plugins through a compatibility bridge, and reimplements the pieces apps rely on, like React Fast Refresh and TanStack Start, but is built natively in Rust. It builds on Rolldown and Oxc, the same Rust foundations Vite itself is increasingly adopting. The difference is how far we go with the Rust, since Vite is a Node.js application that drives a Rust bundler, while OJ is Rust end to end, from the file watcher to the websocket, spawning a small Node sidecar only when an app's plugins or server code actually need JavaScript.

The design choices are all motivated by the preview use case:

  • Compatibility first. The goal is that your app runs unchanged. OJ reads the config you already have and runs the plugins you already use.
  • No JavaScript runtime to drive it. OJ is one binary. It does not install a toolchain into your project, which is ideal for sandboxes that appear and disappear constantly.
  • Built for agent editing, not just human editing. A person saves one file; an agent writes ten in a burst. In OJ the file watcher, module graph, compiler, and hot updates are a single synchronized pipeline, so a burst of edits is coalesced into one consistent update instead of a stream of partial ones. And because the editor here is an agent mid-task, updates can be held and released as one batch, so the preview applies a change once, whole, instead of rendering the half-finished states in between.

You do not configure any of this. It is the engine underneath the preview, and the point is that you never have to think about it.

The numbers

Here is OJ next to Vite on the same projects. The first is a synthetic app with 10,000 components and the others are real open source apps run unchanged.

Project OJ cold start Vite cold start OJ memory Vite memory
10,000 components 1.2s 4.9s ~115MB >1.5GB
Excalidraw ~0.8s ~2.3s 288MB 2.4GB
Twenty (CRM) ~10.2s ~11.3s 1.5GB 4.9GB

The headline is a roughly 4x faster cold start on the synthetic benchmark and, just as important for running previews at scale, memory measured in hundreds of megabytes instead of gigabytes.

These are not toy apps. The test I set myself was to take real, popular open-source Vite apps I did not write, not touch their config, and run them. That is harder than it sounds, because real apps lean on everything Vite offers: regex resolve.alias for monorepo packages, source files outside the app root, TypeScript enums, import.meta.env, plugin virtual modules. Excalidraw and Twenty, a CRM front-end of around 15,000 modules, both run on OJ unchanged.

One caveat keeps the speed numbers honest: they are not fully apples to apples. Vite's cold starts above include vite-plugin-checker, which runs tsc in a background worker to overlay type errors in the browser. OJ does not host that plugin yet, so it skips it and starts without that work, and a different or newer Vite version would shift the speed side too.

That is why the number I care about the most is memory and it is what decides how many previews can run at once: OJ serves these apps on a third to an eighth of Vite's memory. Fast cold starts make a single preview feel instant, but the low memory footprint is what makes running thousands of them at the same time affordable.

In production

Benchmarks are one thing, real people opening real previews are another. We ran OJ against Vite as a controlled experiment across Lovable previews, and the production numbers hold up:

  • Total load roughly halved. The time from opening a preview to a usable app dropped from 17.4s to 8.0s at the median.
  • Sandboxes ready almost 5x faster. Sandbox acquisition fell from 14.5s to 3.0s at the median, a direct payoff of the lighter OJ image.
  • Even the slow tail is faster. The dev-server portion improved from 15.8s to 9.6s at the 90th percentile.
  • The dev server itself is far lighter. In a Lovable sandbox the dev server process runs on roughly 6.5x less memory than node/Vite, before your app has even loaded.

The shape is the one we expected: the biggest wins are in bringing a sandbox up and getting the app on screen, which is exactly where a lighter engine matters most.

What this means for builders

You do not have to do anything. As we roll OJ out across previews, the app you are building opens faster, the edit-to-preview loop tightens, and the sandbox behind it is more efficient. Nothing about how you build changes. The preview is just quicker to show up and quicker to react.

Because OJ aims to run your app unchanged, the plugins and config you already depend on keep working. If you ever hit an app that behaves differently on OJ than it did before, that is a bug we want to know about, and compatibility is the promise we hold ourselves to.

That is why we are rolling out OJ gradually, a small percentage of previews at a time. We widen it only as we confirm apps keep running unchanged, so most builders will move over without ever noticing the switch, other than the wait getting shorter.

Now open source on Lovable’s GitHub

I started OJ as an experiment, out of a simple frustration: I wanted previews that start instantly without a heavy toolchain dragging alongside them. You can read that original story in Introducing OJ.

That experiment is now starting to run real Lovable previews, so it belongs in the open, alongside the rest of the work we share. Today OJ moves from my personal repository to the Lovable GitHub organization, at github.com/lovablelabs/oj. It remains what it has always been: Vite-compatible, honest about its limits, and open for anyone to read, run, and contribute to.

More to come

This is only the start. Right now we are building experimental features into OJ aimed squarely at making previews faster still, and there is a lot we are not ready to talk about yet. We will share them as they land, so keep an eye out: there is more to announce soon.

Start building at lovable.dev, and soon your next preview will be faster than the last.

Raphael Amorim

Raphael Amorim is an engineer at Lovable and the creator of OJ. He builds developer tools in Rust, from the Rio terminal to the Jam language, and previously led Rust adoption at Viaplay after stints at Spotify, GoDaddy, and Globo. He cares about craftsmanship and fast, quiet tools that get out of your way.

Read the whole story
emrox
2 hours ago
reply
Hamburg, Germany
Share this story
Delete

Do You Still Read the Code?

1 Share


There is considerable difference between that question and a more innocuous “do you read the code?” The addition of still smuggles with it a theory of progress: reading code is something on its way out, like memorising phone numbers or unfolding paper maps, and the asker seems to want to know if you by chance aren’t one of the obscurantists still clinging to the old ways.

I use AI extensively, and I read what it produces. This is a deliberate choice about how I want to develop software, at least at my job, where I’m expected to be reasonably responsible for the code that I commit and deploy. Other people make a different choice, sometimes with considerable care. But we have begun sharing codebases without necessarily agreeing on what either path asks of our colleagues.

It is very hard to tell which choice will prevail. The still presumes that the matter has been settled, and indeed producing a working application these days has become quite a bit easier. But finding out what it costs to maintain it through changes of requirements, developers, and tooling takes considerably longer. We are making commitments with respect to how teams work now, and their consequences will only later be felt and understood. The confidence with which either mindset announces its victory seems somewhat premature.

Accelerators and vibecoders

As far as I can tell, there are two prevalent approaches to using AI these days.

Accelerators use AI to help translate their understanding into code. They intend to retain enough understanding of the implementation to explain the reasoning behind the translation from intent to code, anticipate the consequences of changes, and maintain the resulting model and its implementation. Reading the generated code is part of that commitment.

For accelerators, language models and harnesses exist in roughly the same category as text editors and their plugins: they can now code faster. They invest in their continued ability to explain and change the implementation. Large changes are slow to review, a generated diff that is determined to incorrectly implement a model is rewritten, cognitive debt1Marginnote storey1Storey, M.-A. From Technical Debt to Cognitive and Intent Debt: Rethinking Software Health in the Age of AI. arXiv 2026; p. 2 piles up whenever the team’s reading falls behind the generating, and the whole thing requires discipline that is very hard to keep.

Vibecoders aim to delegate implementation and its continued revision to AI. Their attention moves towards specifying the desired behaviour, supplying context and domain knowledge, and establishing ways to determine whether the result is satisfactory. Understanding every implementation detail is no longer an intended product of their work.

Vibecoders expect language models to abstract away implementation, putting them in the same category as compilers and frameworks: there should no longer be a need to understand technical details. They invest in their continued ability to specify, regenerate, and evaluate code. Intent debt2Marginnote storey22Storey 2026; p. 3 may accumulate as requirements are rewritten or forgotten, context drifts between sessions, engineering time goes into curating what the agents get to see to keep them away from the “dumb zone,”3Marginnote horthy3Horthy, D. No Vibes Allowed: Solving Hard Problems in Complex Codebases. YouTube 2025; 5:55 and the whole thing stands or falls with the quality of a model that is controlled by Anthropic or OpenAI.

The distinction concerns the developer’s relationship to the output, rather than how much of it the model writes.4Marginnote willison4Willison, S. Not all AI-assisted programming is vibe coding (but vibe coding rocks). 2025 An accelerator might generate almost every line of a feature and still understand what was built, taking ownership of the reasoning behind it. A vibecoder might spend considerable time refining a specification and its acceptance criteria, while deliberately treating the resulting implementation as disposable. Being an accelerator doesn’t require knowing the answer before asking the model—you can use generated code to explore a problem you don’t yet understand, provided that understanding is something you intend to acquire before the code ends up on the master branch.5Marginnote abstain5There is also a third group that rejects AI for programming at all. The objections I’ve come across have mostly been legal (usually copyright-related) or ethical, and while they deserve a serious discussion, it’s something outside of the scope of this analysis. What I haven’t come across is an organisation building commercial software that avoids AI on pragmatic engineering grounds: because they believe the generated code makes their software worse, and in the end costs them more than it saves. If you work in one, feel free to get in touch. I’d very much like to hear about it.

Naur is still undefeated

My own preference comes from what I think programming is for. I wrote before about how programming is essentially pure applied philosophy. I hadn’t read, at that time, Peter Naur’s essay,6Marginnote naur6Naur, P. Programming as Theory Building. Microprocessing and Microprogramming 1985 since brought to renewed prominence by the advent of LLMs, making a similar point thirty-five years earlier.

It is essentially the same argument, made better, by someone much smarter: the code is not the real product of programming. If anything, we mistake the code for an asset, while more often than not it’s indeed a liability. The real product, the asset, is the model, or the theory, behind it. The theory is the kind of knowledge that lets a person not merely do something, but explain it, answer questions about it, use it to project the future, and adapt it if circumstances change. The programmer who possesses it is capable of three things:

“The programmer having the theory of the program can explain how the solution relates to the affairs of the world that it helps to handle. (…) The programmer having the theory of the program can explain why each part of the program is what it is. (…) The programmer having the theory of the program is able to respond constructively to any demand for a modification of the program so as to support the affairs of the world in a new manner.”

In other words, source code is only one kind of product of the activity of programming, but because it’s more visible, it’s treated as more valuable than the understanding acquired while producing it. It’s as if we treated the steam coming out of a coal power plant cooling tower as the main output, rather than the electricity, merely because electricity is invisible.

A part of the job of a software engineer is to name and structure the parts of the business which have until now been understood only implicitly. This has benefits outside of the code: it can help the people whose work we are modelling understand what they do and see aspects of their work in a new light.

Programming is one way to sort the grains of sand of reality.7Marginnote pirsig7Pirsig, R. Zen and the Art of Motorcycle Maintenance. Vintage 2004; p. 72 We distinguish one thing from another, give distinctions names, and build a system whose behaviour lets us discover where our sorting was useful, and where it was mistaken.

Naming things in terms of their immediate appearance locks us into a certain mode of understanding of the product which may be accidental; naming them after their essential attributes is more flexible, but requires much more effort to discover and structure. And running software can only test the consequences of the sorting. Judging whether the model fits the domain still requires contact with the people and processes being modelled. A green test suite only proves that the program does what you said, not that what you said corresponds to reality.

How a programmer understands the domain changes as he works through the implementation. You might discuss a requirement or even whiteboard it, but your conceptual analysis might not survive first contact with the code. When you must account for every case, you might completely change your understanding of the problem and be forced back to square one.

The implementation, then, is not merely a translation of the specification into runnable code, but one of the places where it is revised. Vibecoders seem to bet that the theory can be built by specifying and running software, without dealing with its implementation. I am not so sure about that.

Choice and drift

Choosing the accelerator or vibecoder approach involves different commitments, even though the same person might choose differently for different projects, or even submodules within the same project.

For example, I might lean into vibecoding in throwaway or exploratory projects, where I don’t actually care about the underlying implementation and just want to see something on the screen. The difficulty is that one can cease to maintain an understanding of the implementation without ever consciously thinking about how to correctly delegate it. You start skimming the diff instead of reading it, you need a lot of time to recall or even come up with a justification for a specific implementation choice, and eventually the only practical way to find out what it is that you’ve actually built is to ask the model, with no way to verify if what the model tells you is correct.

This is why I don’t think of the two approaches as some kind of spectrum. You can be an accelerator in one module and a vibecoder in another, but not halfway in either. A drifting accelerator doesn’t end up somewhere between the two approaches; he ends up a vibecoder by default, without the harness around specifications and evaluations that a deliberate vibecoder would have built to make up for the missing theory.

For my own commercial work, reading every line of the generated code is a good way to make sure I don’t drift. It doesn’t guarantee my understanding, but it provides repeated opportunities to find out where the understanding and the implementation diverge.

And they diverge because agents still make dumb choices, and often don’t respect some human dimensions, like time, that aren’t expressible as textual output. An agent that added tests just looks at the terminal output; it doesn’t really matter to that agent that the tests now take three times longer to run. But speed matters to a human. Likewise, agents with polluted context windows drifting into the “dumb zone” will start making obvious local mistakes like declaring React components inside other components, or violating the rules of hooks.

A marriage of inconvenience

I don’t want this to sound like an accelerator manifesto, because I am entirely open to the possibility that the vibecoders are right and AI will make looking at code obsolete—I’m just not seeing enough compelling evidence for that conclusion yet.

What I am certain of, though, is that there is one obviously harmful practice: putting people who prefer different approaches on the same team without establishing expectations and boundaries beforehand, and then keeping to them.

An accelerator may inherit the work of reconstructing understanding that the author never intended to retain or never had in the first place. A vibecoder may be asked to explain incidental implementation choices, even though he spent a considerable amount of time refining his development process to intentionally make those choices disposable. Either can make the other’s work harder by imposing an unstated maintenance expectation.

In ordinary correspondence, sending someone unfiltered AI output is impolite. But when it starts to concern code, intent, and responsibility for issues in production, courtesy becomes an engineering concern. Before merging changes, colleagues need to know how those changes are meant to be maintained: through a developer’s understanding of the implementation, through specification and an established process of code generation and rigorous testing, or through some combination of the two, as long as it’s clear which parts are which.

Whether reading is enough

None of this makes the accelerator’s position comfortable.

Skills deteriorate when they are not used, and it remains to be seen if merely reviewing AI-generated code, rather than typing it out, is enough to take over and switch back to manual coding if the situation should demand it. Some circumstances that were often speculated about, such as the major AI labs going bankrupt or hiking prices, seem to be no longer a concern (we have access to many providers of open-weights models of high enough quality to trundle along if it comes to it), but there might be some dangers to automation that we do not foresee.8Marginnote bainbridge8Bainbridge, L. Ironies of Automation. Automatica 1983 (!!) And perhaps whoever inherits a vibecoded, or even accelerated, codebase might find it prohibitively difficult to maintain.

Declaring that a human remains responsible is easy. Arranging the work so that the human remains capable of exercising that responsibility is considerably more difficult and requires very multidimensional decision-making. It might turn out that the accelerator approach is just a fast track to burnout.

Reviewing everything involves constraints on how much unfamiliar work you can do at once. When coding with AI, you still need to make sure to model your requirements and ensure that the implementation doesn’t drift; otherwise the job of self-reviewing the output is the worst kind of work—“very boring but very responsible, yet there is no opportunity to acquire or maintain the qualities required to handle the responsibilities.”9Marginnote bainbridge29Bainbridge 1983; §1.2

It’s a conscious choice of a demanding practice whose success requires more than good intentions. If software development is ever fully automated, having programmers perform manual coding tasks just to maintain their skill might become a necessary cost for software companies in order to have someone around who can take over in a moment of need.10Marginnote bainbridge310Bainbridge 1983; §2.3

Intent to code

What the AI revolution seems to have revealed about code review is that we never cared about the quality of the code in itself, but about the understanding of the product expressed by the quality of the implementation. Code quality was a useful proxy for that understanding in the time before Claude Code, but a language model can now feign that understanding convincingly. The presence of generated code in the codebase makes it more important to examine the understanding and the implementation separately.

A reviewer needs to distinguish requirements, deliberate implementation decisions, inherited conventions, and choices for which no rationale was recorded. Those distinctions should remain connected to the code as it changes.

The point is not whether a specific piece of code was generated or typed on a keyboard. Humans make incidental choices that are hard to explain, too, but it’s considerably more difficult to make a great many of them and still end up with working software. Agents do that all the time, but the fact that they do so is not a reason to dismiss them outright: it’s still entirely possible for them to implement explicit decisions faithfully.

Consider the following story: the business requirement is that a user may request password reset links and that they expire. A developer chooses a particular expiry period. An agent chooses how to represent and check it. The resulting code implements those decisions in several places, but the intent is lost—when a reader comes later and sees a value of expiryTime = 6h, he can see what the software does, but the six hours could have come from several places: an explicit business requirement, an existing convention, a considered trade-off, or a guess that no one challenged. To decide whether the value should change, the reader needs to know what justified it and whether those circumstances still hold. The decision’s result is in the code, but on its own it doesn’t preserve enough of its history to reconsider it fully. This is intent debt, and reading every line of the code doesn’t pay it off.

One promising way agents can help here is by leveraging their ability to summarise, letting a reviewer trace those relationships and see where a choice lacks an explanation. If you review the code yourself, you can use a tool like Crit to make sure the implementation didn’t stray from what you intended. Or you can use CodeRabbit’s Change Stack, or my own intent-stack skill, to gather context and generate an aid for the reviewer.

As for automation, greater delegation makes durable goals, constraints, validation criteria, and relevant context increasingly difficult to preserve as the generated codebase grows. Simultaneously, that preservation becomes increasingly important with the growth of the number of lines of code, because the agents doing the implementation might make contradictory decisions simply because they didn’t chance upon the relevant piece of context, or they ascribed authority to information that was meant to be disposable. Those records must remain usable when sessions end, agents change, and the implementation is regenerated.

The various experiments in building “software factories” and “graph engineering” seem to me to be attempts at making that delegation deliberate by cataloguing intent in ever more fractal structures of summary, so that trees or graphs or swarms of agents can communicate at different levels of generality without polluting each other’s context windows with things that aren’t relevant to them. I’m not very in tune with this approach, but a reasonable starting point might be reviewing StrongDM’s account of their software factory, which runs on two rules: no writing code by humans, and no reviewing code by humans. Instead, they validate agents’ work against scenarios kept outside the codebase.11Marginnote wsff11For an opposing view, see Horthy, D. Why Software Factories Fail

Two paths

There are, then, at least two kinds of progress in AI-assisted programming: one helps developers understand and interact with the implementation, and one aims to remove the need for that interaction altogether. While the latter seems to be getting more of the limelight, these are different paths, they require different tools and different approaches. Both may improve, but it does not follow that the goal of the accelerator is to become a vibecoder. Ceasing to read code is not, in itself, progress.

But before asking whether your colleague still reads code, perhaps consider whether you’re still expecting him to maintain yours.

Read the whole story
emrox
4 hours ago
reply
Hamburg, Germany
Share this story
Delete

EuroBirdPortal - bird migration visualization

1 Share

Link

Social

Embed this visualization

(Select left or right map)

L R

Read the whole story
emrox
1 day ago
reply
Hamburg, Germany
Share this story
Delete

React 19.3

1 Share
React 19.3 adds new features like View Transitions, Fragment Refs, browser(), Trusted Types, and more.
Read the whole story
emrox
1 day ago
reply
Hamburg, Germany
Share this story
Delete

On-device models

1 Share

Today we're launching Desert Ant Labs, a European frontier AI lab building opinionated on-device intelligence. We believe the best path to efficient intelligence starts on-device.

We're building small, specialized models for audio, vision, and text – each model answers in milliseconds, and costs nothing to run, so you can put intelligence in every product interaction, without being limited by token cost or inference speed. Small enough to run on a five-year-old phone, fast enough to use on every frame or keystroke, and better than the API call you're already paying for.

The first 18 models are live today (12 stable and six in beta), accessible via one SDK for Swift, Kotlin, and JavaScript. One model per task, each built to be the fastest way to complete that task on a device:

  • Voz: transcribe 10 minutes of audio in two seconds on an iPhone – 4.7x faster than Whisper – with a start and end time on every word.
  • Clear: a 9MB model that can turn a five-minute laptop recording into studio quality audio in one second.
  • Redact: mask names, addresses, and card numbers, in real time, in 27 languages, so they never reach your servers.
  • Tongue: identify 84 languages from three words, with a 2MB model.
Language ID accuracy, three words in

Tongue · 2MB 0.933

293MB detector 0.887

Tongue names the language from three words, scoring 0.933 at 2MB against 0.887 for a 293MB detector.

And that's just to name a few. You can find full specs and benchmarks for the other fourteen, on desertant.com/models and Hugging Face. Every model is free up to 100k monthly active devices. No tokens, no logins.

Personal data caught, by system

Redact · 12MB 88.8

GLiNER-PII · 2.3GB 91.1

Rampart · 14.7MB 61.4

OpenAI filter · 3GB 60.2

Redact catches 88.8% of the personal data in a text, close to the 2.3GB GLiNER-PII, from a 12MB model.

We're building this in Europe, where "on-device" is the sovereign default. The data never leaves your customer's hands, the feature never depends on someone else's cloud, and what's never been uploaded can never be compelled.

How we got here

For five years we've been building our video app, Detail, with an on-device first approach. But when we introduced features like Auto Edit to create short clips, or audio enhancement for podcasts, we had to fall back to cloud APIs. And as the popularity of Detail grew, so did our infrastructure bills.

Every few months I'd hunt for useful on-device models. I'd surf Hugging Face for a model that could find filler words or clean up a recording. And, every June, we'd get great new tools to build with but the industry wasn't moving fast enough. The foundation was there: the chips, Core ML, the research. What was missing was everything between that foundation and actually implementing a feature in your app: a model you could drop in and ship with a few lines of code.

So, we trained the models ourselves. It turns out training a model is a product design challenge, and product is what we know. We designed models and local inference that beat cloud services on speed, quality, and cost, and outperform other local and cloud models on the task itself, at a fraction of their size.

We replaced Dolby for better, faster audio enhancement with Clear, and made our on-device transcriptions 5x faster with Voz. We also replaced Claude Sonnet with Clips, our 284MB model that turns a 10-minute video into a dozen clips in 5 seconds – 10x faster and using 470x less energy than Sonnet, with the same quality.

Clear audio enhancement speed, 5 minutes of audio

iPhone 16 Pro 302x

MacBook Pro (M5) 345x

Clear enhances, masters, and re-encodes a clip on the device, best of three, from a 9MB model. 302x realtime on a phone. Transcription speed, 30 minutes of audio

Voz 319x

Apple SpeechAnalyzer 78x

Whisper large-v3-turbo 50x

Realtime factor over 30 continuous minutes on an M3 Ultra. Voz reaches 298x on an iPhone 17 Pro.

Detail 6, which will launch with iOS 27, replaces all of our cloud APIs with our own models, running entirely on the device.

We've all spent the past few years building with LLMs as if they were just another API. And, amid the hype around generalist frontier brains, we almost forgot they're not the only option.

Every developer I talk to has a wishlist of on-device models they'd build if cost wasn't a factor, or a feature they're bleeding tokens on that they'd happily swap for a local model. A call that runs the same way a hundred thousand times a day: cleaning a recording, tagging a photo, pulling a date out of a sentence, catching a name before the text hits your servers. None of these needs a frontier model.

NVIDIA's own researchers pulled apart three agent systems and estimated that 40 to 70% of their calls to a large model could go to a small, specialized one instead.

The compute is already paid for

The industry will spend about $450 billion on data centers this year. Meanwhile, the world ships more than a billion phones, tablets, and laptops with increasingly capable chips, perfectly suited to these kinds of tasks. There's more compute available in people's hands than in every AI data center on earth.

We have an unfair advantage with free inference. No per-call cost, so a feature runs on every message instead of the ones you can afford to check. No round-trip, and your customer's data never leaves the device. When inference costs nothing, the way we build products changes entirely.

Little brains in every product

To build with local models, the developer experience has to get a lot better. You need models you can use commercially, that beat the alternatives on your task in speed and quality, that you can drop into your app with a few lines of code, and are easy to discover.

Think of the first hundred models as the cerebellum, the little brain. The little brain handles the always-on work – balance, timing, the skills you never think about, so the rest of the brain is free to think. That's what we're building first: fast, specialized models for the work that runs all day, on the device, for free.

Then comes the cortex, the layer that decides which model answers. A small local model first, a bigger one when the job requires it, and the cloud only when the work has to leave the device. As open research advances and device silicon becomes more capable, the local models grow, and we'll train larger ones ourselves. Frontier intelligence, built from the small end up.

Cloud labs ship neutral models because per-token pricing needs a neutral model. Every Desert Ant model ships with a default we choose, and the levers you need to change that default. We optimize the model and the runtime together: on an iPhone, Clear and Voz run on the Neural Engine, and in the browser, Clear's same weights run through WebAssembly.

The SDK

Ready to get started? You can implement Desert Ant models in your app with our native Swift, Kotlin, and JavaScript SDK, available on GitHub.

Our docs are written for developers and agents and you can try the models on your Mac with the CLI, or in your browser on Hugging Face.

Building something cool with our models, or want to build them with us? Get in touch.

Read the whole story
emrox
6 days ago
reply
Hamburg, Germany
Share this story
Delete
Next Page of Stories