Build1 publisher3 min readPublished
Lovable rebuilt Vite's dev server in Rust to pack more sandboxes onto each host
OJ moves the file watcher, module graph and hot updates into a Rust binary and starts Node only for plugins. Lovable reports median sandbox acquisition dropping from 14.5 seconds to 3 seconds, and Vite's creator calls the headline cold-start benchmark somewhat misleading.
The Engineer · Build desk

What happened
- Lovable has started replacing Vite inside its cloud preview environments with OJ, a Rust build tool written for running around one million short-lived development sandboxes a day.
- In a controlled production rollout the company reported median sandbox acquisition time falling from 14.5 seconds to 3 seconds, and dev-server process memory dropping by roughly 6.5 times.
- Both OJ and Vite bundle with Rolldown and parse with Oxc, the VoidZero projects that already power Vite 8.
- Against Vite's own bundled development mode, the current benchmark puts cold start at 1,315 milliseconds for OJ and 1,528 milliseconds for Vite on a 10,000-component test.
- In that same test OJ used 115 MB of memory against 1,751 MB for Vite's bundled mode, while hot module replacement was effectively even between them.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- cost Memory cannot be oversubscribed the way CPU can, so the dev server's idle footprint, not its cold start, is what decides how many previews Lovable fits on a host.
- constraint Anyone reusing these figures inherits Lovable's plugin set: the TypeScript checking OJ skipped still has to run somewhere, and running it brings the Node host back.
- precedent If rebuilding one layer of a dependency to fit house infrastructure becomes routine, maintainers get benchmarked against forks that only have to support a subset of their paths.
- contradiction Which Vite mode you pick as the baseline changes the speed verdict from fourfold to a sixth, and the memory gap holds across that choice while the speed gap largely does not.
The Rust binary owns the dev server. It reads an existing `vite.config.ts` and runs Vite and Rollup-style plugins through a compatibility bridge, starting a small Node process when an application needs JavaScript plugins or server-side modules [4]. "It is not an entire rewrite of Vite," Vite creator Evan You said on X [5]. The Node process comes back whenever a config asks for it. Plugin-free, OJ's memory advantage in the 10,000-component test is about fifteen times [1]. With the Node plugin host running against a real `vite.config`, OJ creator Raphael Amorim said tests still showed OJ using less than one-third as much memory [13].
The rollout ratio Lovable reported is about 43 percent of the plugin-free lab ratio [6]. Its production figure sits between those two. Lovable engineer Jonathan Grahl explained why the company optimises for that axis: "Memory is a dedicated resource (compared to CPU which is highly shareable); which makes it expensive," he said [11]. He said the dev server was idling at around 400 MB, and that Lovable hoped to push it lower so it could pack more sandboxes onto each host [12]. That idle number is roughly 3.5 times what OJ used in the benchmark [2].
Lovable first put bundle-mode OJ against Vite's default unbundled development mode: about 1.2 seconds to cold start versus 4.9 [7], roughly four times [5]. You called that benchmark "somewhat misleading" because Vite has its own bundled development mode [8]. Bundled against bundled, the gap is 213 milliseconds, about 16 percent [3]. Lovable also disclosed that one of its real-application comparisons ran `vite-plugin-checker` on the Vite side, which starts a TypeScript worker that OJ skips because it does not support the plugin [14].
Lovable said the production gains came partly from a smaller binary and sandbox image cutting provisioning time before an app could serve [15]. The 14.5 seconds covers sandbox acquisition, not dev-server start. The saving is 11.5 seconds per acquisition, a 4.8x reduction [4], and it holds only if you are pulling a fresh sandbox image per session around a million times a day [1] and counting that pull inside your dev-server metric. On a laptop that starts one dev server after breakfast, what you get is the 213 milliseconds [3].
pnpm's Rust rewrite was led by its original maintainers, Rspack preserves much of webpack's configuration and API, and Biome ships a Rust formatter with high Prettier compatibility [18]. socket.dev distinguishes OJ from those by its target: one layer of a general-purpose dependency, rebuilt around a single company's infrastructure, in a piece headlined around AI lowering the cost of forking open source [19][23]. The support offered for the AI part is You's expectation that the approach will become much more common [19].
Vite covers a wide range of frameworks, plugins, application patterns and downstream tools; OJ only has to cover the paths Lovable's preview sandboxes use [21]. That narrower coverage is what produces the numbers. The compatibility work Amorim documented is the cost of staying close to Vite: regex aliases, source files outside the application root, TypeScript enums, `import.meta.env`, plugin virtual modules [17]. "These are not toy apps," he wrote of Excalidraw and Twenty, which "both run on OJ unchanged" [16]. Twenty's frontend alone contains roughly 15,000 modules [17].
What to watch
- Whether Lovable gets the dev server below its 400 MB idle figure, which is what sets how many sandboxes fit on a host.
- Whether OJ adds vite-plugin-checker support, letting the largest speed comparison be rerun with the TypeScript worker running on both sides.
- Whether other companies publish single-layer forks of general-purpose tooling and benchmark them against the general tool.