# Chad Fowler's "Phoenix Architecture"

> Source: <https://stevekrouse.com/phoenix>
> Published: 2026-06-30 19:56:57+00:00

June 30,2026

I kept hearing about Chad Fowler's
[Phoenix Architecture](https://aicoding.leaflet.pub/), and after
[Charity Majors' endorsement](https://charitydotwtf.substack.com/p/ai-demands-more-engineering-discipline),
I figured it was worth an investigation.

The core premise: LLMs make code cheap to generate, so code should be disposable.

The most compelling parts are the analogies to immutability:

Immutable infrastructure. Stateless services. Containers. Blue-green deployments. Infrastructure as code.

These ideas all share a common premise: never fix a running thing. Replace it.

AI pushes this premise beyond infrastructure and into application code itself. When rewriting is cheap, editing in place becomes risky. Mutation accumulates entropy. Replacement resets it.

When you edit code in place, you're doing the software equivalent of SSHing into a production server and tweaking a config file.

I whole-heartedly agree that mutating something low-level is bad. Regenerating
it from scratch from something high-level is good. This is how we moved from
JQuery to ReactJS or from Binary to Assembly to C to JavaScript – higher level
abstractions that let us *generate* disposable lower level artifacts.

But that begs the question: regenerate from *what*? I sure hope you don't mean
natural language specs! Don't make me get the comic out again.

I made this case at length in
[Reports of code's death are greatly exaggerated](https://stevekrouse.com/precision),
but in brief: natural language is a terrible "source of truth" for software. As
Bertrand Russell says, "Everything is vague to a degree you do not realize till
you have tried to make it precise." If today's code feels too low-level and
boilerplate-y in a way that makes you want to burn it down and regenerate it
from scratch, the fix is to climb incrementally higher to better programming
abstractions that let you convey your higher-level intent while still being
precise and mastering the inherent complexity.

It's a category error to conclude that because code is cheap to generate, we should treat it all as disposable. It's leaning a bit too far into the vibes of 2025 and Gas Town, when designing around lots of slop seemed like the thing to do. I don't know if we've yet hit peak code slop – probably not quite yet – but it feels like that's right around the corner.

So while I don't agree with the solutions of the Phoenix Architecture, I do agree with the problem:

The limiting factor is no longer writing software, but understanding, evaluating, and governing it.

Peter Naur's
[Programming as Theory Building](https://pages.cs.wisc.edu/~remzi/Naur.pdf), has
a similar theme: the code doesn't represent very much of the "theory" that made
it. However, Naur warns you against thinking you could put all that "theory"
into specs or docs. It lives in the heads of the creators.

But now that we have ephemeral machine "heads" – where does that understanding live long-term? It kinda lives in the documentation that the machines write for themselves, but at least for now, we all know that doesn't scale the same way human understanding does.

For improving code understanding, I always return to Glen Chiacchieri's
[A Human-Readable Interactive Representation of a Code Library](https://glench.github.io/fuzzyset.js/ui/),
a delightful explorable explanation of a fuzzyset library. (If you care at all
about code undersatnding, please go play with it!) Now with vibe coding, there's
very little excuse to not generate artifacts like these for *every* piece of
software we build.

My personal thesis is that making software understandable to humans also makes it understandable to LLMs, and vice versa, so investments in understandability do double-duty. This is great news! We can keep humans and machines both in-the-loop at the same time. I think that's the path towards accelerating development, and making the most of how cheap code is now to generate.
