Simplicity Is the Ultimate Sophistication
The entire history of software development is a history of middleware accumulation.
Each generation solved a coordination problem by inserting a layer between intent and execution. Databases mediated between memory and retrieval. APIs mediated between services. Frameworks mediated between developer intent and browser rendering. Orchestrators mediated between containers.
The Middleware Era Was a Compression Artifact
Software architecture didn't accumulate layers because layers are good. It accumulated them because human cognition couldn't hold the full pipeline. No single developer could reason about user intent, data modeling, API design, frontend rendering, deployment, and observability simultaneously. So the industry decomposed the problem into specialties, each with its own tools, its own platforms, its own career track.
The decomposition was real. The cost was real. But the necessity was contingent on a specific limitation: the cognitive bandwidth of individual human developers.
Middleware is what happens when the agent executing the work can't see the whole. Each layer is a prosthetic for a missing capacity. The database abstraction exists because the developer can't hold raw storage semantics while thinking about business logic. The API gateway exists because no one person designs both the service and its consumers. The framework exists because hand-writing DOM manipulation while reasoning about state is too much cognitive load.
Every middleware layer is a marker: the executing agent couldn't hold the whole pipeline.
AI Knows How to Build, Not What to Build
Here's the structural asymmetry that defines the current transition: AI agents can hold the full context of a pipeline simultaneously—data schema, business logic, interface rendering, deployment configuration—but they don't originate the intent. They know how. They don't know what. At least not yet—and perhaps not in principle, because "what to build" isn't a knowledge problem. It's a desire problem, a taste problem, a problem of caring about outcomes in a world you inhabit. The agent doesn't inhabit the world. The builder does.
This means the middleware era's cognitive bottleneck doesn't get solved by replacing the human. It gets solved by restructuring the relationship between human and machine. The human carries intent—the "what" that, at least for now, only the human can supply—and the agent carries execution capacity across the full pipeline. One builder, orchestrating one or more agents, building whatever they want to build, end to end.
The old model: teams of specialists, each owning a layer, coordinating through process and middleware. The new model: one person with a vision, directing agents that can execute across every layer simultaneously. The coordination overhead that justified middleware was never about the problem—it was about the team. When the team collapses to one builder plus agents, the coordination layers collapse with it.
This doesn't mean middleware disappears. It means middleware stops being the organizing principle. The layers that existed to partition cognitive labor between specialists become optional—sometimes useful for performance or isolation, but no longer structurally required for the work to happen at all.
The shift is subtle but pervasive. It's not "AI writes code faster." It's that the unit of work changes from component to pipeline, and the unit of agency changes from team to individual. The builder doesn't manage a frontend team, a backend team, and a DevOps team. The builder describes what should exist, and the agents make it so.
The Residue Mindset
But even builders who've adopted the agent model carry the old structure in their thinking. There's a residue—not an error but a lag, the natural persistence of patterns optimized for previous constraints.
The residue looks like this: the builder instructs the agent to assemble pre-existing components into something new. Use this framework. Call that API. Wrap this library. Deploy on that platform. The agent executes end-to-end, but the conception is still middleware-shaped. The builder is still thinking in layers—just orchestrating them faster.
This is building from what was built before, by others, into something to be used by others. Every link in that chain carries assumptions, abstractions, and constraints that were optimized for a different context, a different user, a different era. The framework was designed for a class of applications, not this application. The API was shaped by its builder's priorities, not the end user's actual need. Each dependency is someone else's projection of what you might want, and each projection distorts.
The deeper shift isn't builder-plus-agents assembling components faster. It's removing the structural necessity of the components themselves.
Build With the End User, Not Around Them
The question the residue mindset never asks: why is there anything between the end user's need and the raw capability that could serve it?
In the middleware era, the answer was obvious—humans couldn't bridge that gap directly. You needed layers of abstraction, pre-built components, frameworks, platforms, each reducing the distance by one step. The end user was always many translations away from the raw input. And because each translation was expensive, software had to be general-purpose to justify the cost. One application serving a million users, most of whom got an approximation of what they actually needed.
When AI agents make code generation nearly free, two things happen simultaneously.
First: the builder moves closer to the end user. Instead of building general-purpose software and hoping it approximates enough users' needs to be viable, a builder can create applications tailored to specific users, specific contexts, specific moments. The distance between "what this person actually needs" and "what the software does" collapses. Software becomes just-in-time: built for this user, for this need, right now.
Second—and this is the part the middleware mindset gets wrong: the ecosystem doesn't shrink. It explodes. When building is cheap and specificity is free, you don't get fewer applications serving more people with general-purpose approximations. You get vastly more applications, each precisely fitted to its user. The long tail of software that was never economical to build—too specific, too niche, too few users to justify the development cost—suddenly becomes buildable. Not all of it should be built; cheap production doesn't guarantee value. But the constraint shifts from "can we afford to build this?" to "is this worth building?"—which is a better question to be answering.
And the most radical extension: the end users themselves become builders. If the gap between intent and execution has collapsed to "describe what you want and the agent builds it," the distinction between builder and user starts dissolving. The end user who knows what they need is already the most qualified person to specify it—they just lacked the how. The agent supplies the how. No intermediary builder required.
This is the full arc: from teams of specialists building middleware for other developers, to individual builders orchestrating agents closer to end users, to end users directly commanding agents to handle their raw inputs and produce their specific outputs. Each step removes a translation layer. Each removal eliminates a place where intent gets distorted. And each step creates more software, not less—because every translation layer that previously made specific solutions uneconomical has been removed.
The new ecosystem is larger, not smaller. It's just composed of precisely fitted applications rather than general-purpose approximations.
The Generality Tax
Here's what general-purpose middleware can't escape: it was built for everyone, which means it was built for no one in particular.
A framework designed for generality and compatibility must anticipate thousands of use cases. It ships with abstractions that cover possibilities you'll never encounter, configuration surfaces you'll never touch, and architectural opinions that may directly conflict with what you actually need. You wanted a door; you got a building code. Most of what arrives in the package, you don't want. But you carry it anyway—in bundle size, in cognitive overhead, in the constraints it imposes on how you can structure your own solution.
And all of it was worth it. Every bit of added complexity—the dependency management, the framework learning curves, the abstraction layers, the coordination ceremonies, the configuration files, the build tooling—was a rational trade-off when the alternative was writing everything from scratch at the cost structure of the time. The generality tax was real, but the cost of specificity was higher. You accepted the building code because hiring an architect for every door was unaffordable.
This isn't a flaw in any particular middleware. It's structural. Generality requires packaging what you don't need alongside what you do. The more general the tool, the larger the ratio of unwanted to wanted. Every abstraction layer is a bet about what a typical user might need, and you are never the typical user. Your specific problem, your specific users, your specific constraints—these are always particular, and the general-purpose solution always rounds them off. But when writing specific code cost weeks or months, that rounding was the best available option.
What changes isn't the nature of the trade-off. It's the cost structure underneath it.
End-to-end software built by an agent from a builder's specific intent doesn't have this problem. It gives you exactly what you want and nothing more, nothing less. Not perfectly—no solution is perfect—but as precisely as the intent can be specified. And that precision is something no middleware can provide, because middleware's entire value proposition is not being specific to you.
This is the deeper reason dependencies become liabilities when generation is cheap. It's not just the maintenance cost or the security surface. It's that every dependency substitutes someone else's general-purpose approximation for your specific need. When you couldn't generate the specific solution, the approximation was worth the trade-off. When you can generate exactly what you need for near-zero cost, the approximation is pure loss.
The end-to-end application, built from intent to outcome with minimum dependency, is the first kind of software that can be precisely fitted. Not over-engineered for cases that don't apply. Not under-specified because the framework didn't anticipate your case. Just: what's needed, as it's needed, for who needs it. The fit is precise; the execution quality still depends on the builder's specification and the agent's capability. But the mismatch between need and solution—the gap that generality structurally guarantees—trends toward zero. The agent makes this possible. The middleware era made it unthinkable.
The Agent's Own Residue
There's a deeper layer to the residue problem: the AI agents themselves are trained on the entire corpus of middleware-era software. Every framework convention, every dependency chain, every architectural pattern that accumulated over decades—it's all in the weights. When you ask an agent to build something, its default is to reach for React, import twelve packages, set up a build pipeline, and scaffold the application the way millions of developers did before it.
The agent doesn't do this because it's the best approach. It does this because that's what building software looked like in the training data. The agent has internalized the middleware mindset at the statistical level. It has learned that "good code" means separation of concerns, dependency management, framework conventions—all the patterns that were genuinely good practice when the cost of writing code was high and the cost of coordinating teams was the dominant constraint.
But the cost of writing code is trending toward zero. And this is precisely what the agent's training data doesn't reflect, because the training data comes from an era when code was expensive.
This creates a paradox: the tool that makes zero-dependency end-to-end development possible is itself biased toward dependency-heavy, middleware-structured development. The agent will suggest installing a package for something it could generate in twenty lines. It will propose a microservices architecture when a single coherent program would serve better. It will reach for abstractions designed to help teams coordinate even when there's no team—just one builder with clear intent.
The residue isn't only in the builder's mindset. It's in the agent's weights.
The Cost Inversion the Models Haven't Learned
In the middleware era, writing code was expensive and using someone else's code was cheap. Dependencies were rational. Why write what you can import? The entire open-source ecosystem, the package managers, the framework communities—all optimized for code reuse because code production was the bottleneck.
When AI agents make code generation nearly free, the cost equation inverts. Writing exactly what you need becomes cheaper than carrying what someone else wrote for a different purpose. The dependency that saved you a week of development now costs you in integration friction, update maintenance, security surface, and abstraction mismatch—costs that exceed the near-zero cost of generating a fit-for-purpose solution.
But the models don't know this yet. They were trained on a world where npm install was almost always the right first move. They'll need time—through fine-tuning, through RLHF, through builders who learn to prompt past the defaults—to internalize that the economics have flipped. The cheapest code is now the code that carries no one else's assumptions.
This is why the builder's role matters even more than it first appears. The builder isn't just supplying intent. The builder is also correcting for the agent's training bias—steering it away from the middleware patterns baked into its weights and toward the direct, minimal, end-to-end approach that the new economics favor. The best builders in this era will be the ones who can see past the residue in their own thinking and in their agents' defaults. They'll prompt for outcomes, not components. For directness, not architecture. For the simplest path from raw input to served user, even when the agent's instinct is to scaffold something far more elaborate.
The models will catch up. As more software gets built the new way—minimal, direct, dependency-free—that code enters the training data and shifts the distribution. But we're in the transition period where the agents carry the old world's assumptions, and the builders who recognize this have the advantage.
A Glimpse: Karpathy's Dependency Rip-Out
The trajectory is already visible if you know where to look.
In February 2026, Andrej Karpathy described a workflow that crystallizes everything this essay argues. He was building nanochat and found himself annoyed by the torchao library's implementation of fp8 training—too complicated for what should be a straightforward operation, too many extra casts and calls to torch._scaled_mm. He had the suspicion that the whole thing shouldn't be that complicated. So he pointed an AI agent (Claude, via DeepWiki MCP and GitHub CLI) at the torchao repository and prompted:
"Use DeepWiki MCP and Github CLI to look at how torchao implements fp8 training. Is it possible to 'rip out' the functionality? Implement nanochat/fp8.py that has identical API but is fully self-contained."
The agent went off for five minutes and came back with 150 lines of clean code that worked out of the box, with tests proving equivalent results. This allowed Karpathy to delete torchao as a repository dependency entirely. The self-contained version also happened to run 3% faster—not because anyone optimized for speed, but because removing the generality overhead naturally produces leaner code. That 3% wasn't the point; it was the side benefit. The point was: 150 self-contained lines replacing a library dependency, with nothing in the package the builder didn't need. The performance gain is just what happens when you stop paying the generality tax. The opposite—the overhead we carried for decades—was the cost of generalization in an era when writing specific code was too expensive to justify.
This is the pattern in miniature. A builder with clear intent—"this shouldn't be that complicated"—directing an agent to rip the specific functionality out of a general-purpose library and reimplement it as a self-contained, dependency-free module. The result: fewer lines, faster execution, zero dependency tax, and nothing in the package the builder didn't need.
Karpathy's reflection on the broader implication cuts to the core of this essay's argument: maybe you don't download, configure, and take dependency on a giant monolithic library. Maybe you point your agent at it and rip out the exact part you need. Maybe this means software should be built more like "bacterial code"—less tangled, more self-contained, more dependency-free, more stateless, easier to rip out from the repo. As he put it: "Libraries are over, LLMs are the new compiler."
This sits alongside his microGPT project—243 lines of pure, dependency-free Python that trains and runs a full GPT. No PyTorch, no TensorFlow, no NumPy. Just os, math, random, and argparse. The entire algorithm: tokenizer, autograd engine, transformer architecture, Adam optimizer, training loop, inference loop. The culmination of a decade-long obsession to simplify LLMs to their bare essentials, described by Karpathy as irreducible: "This is the full algorithmic content of what is needed. Everything else is just for efficiency. I cannot simplify this any further."
The two projects together trace the full arc. microGPT shows where the principle leads when pursued to its logical end—zero dependencies, pure algorithm, nothing but what's needed. The nanochat/torchao rip-out shows how AI agents make this practical now—not through decade-long simplification journeys, but through five-minute agent sessions that extract exactly what you need from any codebase and deliver it self-contained.
Scale this principle. Imagine every application built this way—not by painstakingly hand-removing dependencies over years of projects, but by agents that rip out exactly what's needed or generate fit-for-purpose code from intent, carrying zero unnecessary assumptions. The builder says what's needed. The agent produces exactly that. Nothing more, nothing less. The era of dependency-free, end-to-end software isn't a distant vision. It has working prototypes, and the process of producing them is already simpler and faster than the middleware approach.
This is where the platform displacement happens—and it's the part most incumbents will misread.
The previous generation of platforms competed on functionality. AWS competed on how many services it offered. Vercel competed on how smooth the deployment experience was. Stripe competed on how clean the payment API was. Each platform owned a layer and made that layer excellent. They were selling building blocks to builders who assembled.
But if the unit of work shifts from component to pipeline, the unit of agency shifts from team to individual builder, and the end state is users building directly from raw inputs—then the platform that matters isn't the one with the best individual layer. It's the one that enables the most direct path from intent to working outcome, whether that intent comes from a builder or an end user.
The new platforms don't build functionality. They build for the builder—where the builder is increasingly an AI agent, not a human developer manually wiring components.
This inverts the value proposition. The old platform says: "We handle X so you don't have to." The new platform says: "We expose everything the agent needs to handle X through Z without stopping." The old platform reduces complexity by hiding it. The new platform reduces complexity by making the full surface legible to an agent that can hold it all.
Hiding complexity was the right move when humans were the direct operators. It's the wrong move when the operator can see everything and the hiding just creates blind spots and integration overhead.
The Simplicity That Emerges
Here's the inversion that Leonardo's maxim captures: the most sophisticated architecture is increasingly the one with the fewest layers.
In the middleware era, sophistication meant elegant abstractions. Clean interfaces between components. Well-designed APIs. Separation of concerns. These were genuine achievements—they made complex systems buildable by teams of specialists coordinating across cognitive boundaries.
In the end-to-end era, sophistication means something different: how little stands between the builder's intent and working software. How few translations are required. How directly the description of what should exist maps to the thing that exists.
This isn't a regression to simplistic systems. It's the emergence of a different kind of complexity—one that lives in the model's weights and context rather than in architectural layers. The complexity doesn't disappear. It migrates. From explicit middleware that teams maintain to implicit capability that the agent already contains, directed by a builder who knows what they want.
The simplest system is the one where the builder carries the intent, the agent carries the capability, and almost nothing stands between them. Not because simple is easy, but because every unnecessary layer is a place where intent gets lost in translation—and the builder-agent model has no tolerance for lost intent. The builder isn't managing process. They're realizing vision.
What Gets Displaced, What Survives
Not everything middleware does is cognitive scaffolding. Some layers exist for genuinely structural reasons—network boundaries, security isolation, data sovereignty, regulatory compliance. These survive because they're not prosthetics for limited cognition; they're constraints from the operating environment itself.
What gets displaced is everything that existed primarily to make the development process manageable for human teams:
- Framework conventions that standardized how teams coordinated
- Boilerplate that existed to satisfy type systems and build tools
- Glue code that translated between layers that didn't need to be separate
- Configuration that specified what could have been inferred from intent
- Most of CI/CD as currently practiced—the ceremony around deployment that existed because deployment was a separate specialty
What survives is everything that exists because the problem requires it, not because the process did.
The Platform Prediction
The platforms that win the next era won't be the ones that add AI to their existing functionality layer. They'll be the ones that reconceive themselves as substrates for direct intent-to-outcome execution—for builders today, and increasingly for end users themselves.
This means: raw capability exposure over pre-packaged abstractions. Unified context over clean separation. Composability at the flow level over composability at the component level. Making the full pipeline from raw input to served user legible and manipulable in a single agent context, rather than offering the best possible experience for one slice of a multi-slice assembly process.
The companies building "AI features" into traditional middleware platforms are optimizing the wrong unit. They're making individual layers smarter when the structural pressure is to eliminate the layers entirely. Worse, they're reinforcing the residue mindset—teaching builders to think in components when the opportunity is to think in outcomes.
The Acceleration of Diversification
This shift, like every major tool adoption before it, lifts everyone. Even those who refuse to embrace agentic development will benefit from the applications, infrastructure, and capabilities it produces. The rising tide is real. No one opts out of the consequences of a tool that restructures how software gets built—any more than anyone opted out of the consequences of the internet, regardless of whether they personally built websites.
But the gap between those who adopt and those who don't will widen—dramatically. This is the pattern of every consequential tool: shared progress as a whole, accelerating diversification in capability. The printing press made everyone more literate over time, but the gap between those who could publish and those who couldn't widened before it narrowed. The internet lifted all boats, but the distance between digitally fluent organizations and laggards became a chasm before it became a baseline. AI-enabled end-to-end development tends to follow the same arc: universal benefit, uneven distribution, and a transition period where the gap between early adopters and holdouts defines competitive reality.
There's an irony in the distributional dynamics that's worth naming. Those whose positions depend most on the coordination overhead of the middleware era—the framework maintainers, the DevOps specialists, the platform operators—face the sharpest displacement, even though the new structure offers them tools to produce far more than they could before. The resistance concentrates where the positional rearrangement is greatest, not where the capability loss is greatest. These aren't the same axis, and collapsing them obscures what's actually happening.
Meanwhile, those building toward the end-to-end possibility absorb disproportionate friction—skepticism, institutional inertia, dismissal from incumbents who insist the new approach "doesn't scale" or "isn't enterprise-ready." This asymmetry is inherent in adoption curves: the early portion of any transition encounters more resistance per unit of progress than the later portion. The friction isn't a sign that the shift is wrong. It's a sign that the shift is real enough to rearrange positions.
This too is structural, not moral. The resistance comes from the same place the middleware came from—a rational response to the previous set of constraints. The specialists optimized for a world where their specialization was necessary. The platforms optimized for a world where their layer was essential. When the constraints change, the optimization becomes overhead. The pain is real. But the direction of pressure is legible.
Simplicity is the ultimate sophistication—not as aesthetic preference, but as structural prediction. The arc tends toward: specialist teams coordinating through middleware, to individual builders orchestrating agents, to end users building directly from raw inputs with agents as their how. Each stage strips a translation layer. Each layer stripped recovers signal that was being lost. Whether the arc completes, and how, remains open. But the direction of pressure is not.
The most capable architecture is the one that needs the least architecture. The most powerful development model puts the person who knows what they need in direct contact with the capability that knows how to build it. Everything else is residue. And the residue is thinning.