Most developers use Vite and trust it. It's fast, well-designed, and gets out of the way.
But there's a fundamental assumption baked into Vite's architecture — and every other major build tool — that we decided to challenge when building Ionify.
The assumption: every build starts from zero.
This post is a deep look at what that means in practice, what we built instead, and the architectural tradeoffs we made along the way.
The Stateless Build Problem
When you run vite build , here's roughly what happens:
Vite spins up esbuild/Rollup (now powered by Rolldown + Oxc instead of pure Rollup/Babel in many cases)
Each file goes through its plugin chain independently
main.tsx → TS plugin → JSX plugin → output
utils.ts → TS plugin → output
index.css → CSS plugin → output
Everything gets bundled
The next time you run it? Same thing. All of it.
There's no memory of what already ran. The TS plugin doesn't know the JSX plugin already processed a file.…