Ionify vs Vite: What Actually Happens Inside Your Build Tool
Source: Dev.to
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 Ionify challenges.
The assumption: every build starts from zero.
The Stateless Build Problem
When you run vite build, roughly this happens:
Vite spins up esbuild/Rollup (now often powered by Rolldown + Oxc).
Each file goes through its plugin chain independently
main.tsx → TS plugin → JSX plugin → output utils.ts → TS plugin → output index.css → CSS plugin → outputEverything gets bundled.
The next time you run it, the same process repeats. There’s no memory of what already ran; the TS plugin doesn’t know the JSX plugin already processed a file, and the bundler doesn’t know which files changed. The pipeline is stateless by design. This isn’t a bug — it’s a deliberate choice for simplicity and predictability, but it incurs a real cost at scale.
How Ionify Thinks About This Differently
Instead of repeatedly transforming files, Ionify addresses them.
Content‑Addressable Store (CAS)
Every module gets a content hash:
SHA-256(source content + config version) → CAS keyThe result lives in a CAS directory:
.ionify/
cas/
/
/
transformed.js
transformed.js.mapSame content + same config → same hash → skip the transform entirely. No transforms at all for unchanged modules.
The Persistent Graph
Vite reconstructs its module graph on every dev‑server start. Ionify persists it:
.ionify/
graph.db ← sled‑backed embedded KV store (Rust)When a file changes, Ionify runs a BFS over the reverse‑dependency index to find exactly which modules are affected. In a 500‑module project, changing one utility file might invalidate only 12 modules, not all 500.
Version Isolation: Config Changes Invalidate Everything
A persistent cache must handle config changes. Ionify solves this with a deterministic version hash computed from the configuration, ensuring that any config modification invalidates the relevant caches.
The Four‑Tier CAS Architecture
As the system evolved, Ionify introduced four distinct caching layers, each solving a different problem.
Tier 1 — Module Transform Cache
Stores transformed module outputs keyed by the content hash.
Tier 2 — Deps Artifact Store
Caches compiled third‑party dependencies.
Tier 3 — Compression CAS
Pre‑compresses build outputs (Brotli‑11, gzip‑9) once, serving them forever.
Tier 4 — Chunk‑Output CAS
Caches final chunk files produced by the bundler.
Real Config: Migrating from Vite
Below is an example ionify.config.ts from a production project that switched from Vite:
import { defineConfig } from 'ionify'
export default defineConfig({
entry: '/src/main.tsx',
server: {
https: true,
},
resolve: {
// Same aliases as tsconfig — Ionify reads these natively
// Note: if your tsconfig.json is JSONC (comments/trailing commas),
// auto‑alias parsing currently fails — specify manually here
alias: {
'@@': '/',
'@@/Core': '/Core/src',
'@': '/src',
},
extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
conditions: ['import', 'module', 'browser', 'default'],
mainFields: ['module', 'jsnext:main', 'jsnext', 'main'],
},
optimizeDeps: {
include: ['moment-hijri'], // pre‑warm known‑problem deps
sharedChunks: 'auto',
packSlimming: 'auto',
vendorPacks: 'auto',
},
build: {
target: 'esnext',
},
})The project contains over 10 k modules. After migrating to Ionify:
- Cold build: 3.2 s (down from 3.7 s with Vite)
- Warm build: 2.2 s (down from 3.7 s)
The Fundamental Difference
| Build Tool | Core Assumption |
|---|---|
| Vite | Each build is independent. |
| Ionify | Most of the work from the previous build is still valid. |
Both assumptions are reasonable. Vite’s leads to a simpler, more predictable system. Ionify’s approach lets the second, tenth, and CI builds all benefit from prior work, leaving the “transform” side of the diagram mostly empty—not because complexity is hidden, but because most transforms simply don’t run.
Ionify is currently in production use.