Skip to main content

OJ, Vite, and the 'Slop Fork' Future Evan You Is Worried About

ยท 9 min read
Gergely Sipos
Frontend Architect

banner

OJ โ€” nicknamed "Orange Juice" โ€” is a single Rust binary from Lovable that runs a React app the way Vite's dev server does. To be clear up front, because this is where most of the coverage goes wrong: it is not a fork of Vite's source code, and it is not a full rewrite of Vite. It reimplements one layer โ€” the dev-server layer โ€” in Rust, while leaning on the same Rust foundations Vite itself already uses. That correction matters, but it isn't the real story. The real story is the debate OJ set off: a Socket.dev article and a widely-shared Evan You post arguing that AI is collapsing the cost of reimplementing open-source dependencies, and what that does to the ecosystem. If you want the background on why Rust keeps showing up under node_modules, that's a separate post โ€” see The Rust Wave Under Your node_modules. This one is about OJ specifically, and the argument it started.

What OJ actually is (and isn't)โ€‹

OJ is a single Rust binary that runs a React app the way Vite's dev server does. Lovable nicknamed it "Orange Juice."

Start with the two corrections people keep getting wrong:

  • It is not a fork of Vite's source code.
  • It is not a full rewrite of Vite. Evan You's own clarification, verbatim: "It is not an entire rewrite of Vite."

What OJ reimplements is the dev-server layer: the file watcher, the module graph, compiler coordination, hot updates, and WebSocket handling โ€” all in Rust.

Its current plugin/config path explicitly reads an app's vite.config and picks up Vite/Rollup-style plugins through that compatibility layer, while also supporting its own oj.config/oj.plugins entry points, as documented in OJ's pinned README plugin section.

OJ's architecture docs separately describe the post-sidecar design: JavaScript workloads now run in-process in embedded V8 isolates via the Deno runtime.1

OJ's current docs also explicitly describe SSR mode, TanStack Start support, and Svelte 5 coverage in dev, bundle, and build mode.

The architectural insight that gets lost in the "fork" framing: OJ is built on Rolldown (the bundler) and Oxc (parse/transform) โ€” the same Rust foundations maintained by VoidZero that already power Vite 8. The difference isn't which Rust libraries are used; it's how far the Rust goes. Vite is a Node application driving a Rust bundler. OJ is Rust end-to-end, from the file watcher all the way out to the WebSocket. For the Rolldown/Oxc context and who maintains them, see The Rust Wave Under Your node_modules.

The provenance is worth a line: OJ was created by Raphael Amorim (an engineer at Lovable, previously at Spotify, GoDaddy, Globo, and Viaplay) and is maintained by Lovable Labs. It's MIT licensed (ยฉ 2026 Raphael Amorim and Lovable Labs Incorporated), currently at v0.2.5, with the repo at github.com/lovablelabs/oj. Notably, it's distributed via crates.io โ€” not npm:

cargo install oj   # distributed via crates.io, not npm

Why Lovable built itโ€‹

Lovable runs roughly one million short-lived preview sandboxes per day, each with its own Vite instance.

Vite is built for the common case: one developer on one laptop. That's the right optimization target for a general-purpose tool, but it's the wrong one at Lovable's scale. When you're spinning up a million sandboxes a day, the per-sandbox memory footprint is the cost driver โ€” every Vite instance holds a JavaScript runtime, the toolchain, and a lot of memory, multiplied by the sandbox count.

That's the "different constraints" point, and it's what sets up the whole debate. OJ isn't optimizing Vite for everyone. It's optimizing one layer of a general-purpose dependency for one company's infrastructure.

The benchmarks โ€” and why to distrust the headline onesโ€‹

Lovable published a set of comparisons. Here are the synthetic ones:

ScenarioOJ cold startVite cold startOJ memoryVite memory
10,000 React components~1.2s4.9s~115MB>1.5GB
Excalidraw~0.8s~2.3s288MB2.4GB
Twenty CRM (~15,000 modules)~10.2s~11.3s1.5GB4.9GB
caution

Every number in this section is vendor-reported by Lovable, and several are contested. Evan You called the headline synthetic comparison "somewhat misleading" because it pits OJ against Vite's unbundled dev mode rather than Vite's own bundled dev mode. Treat these as directional, not as independent benchmarks โ€” and note the speed and memory results tell different stories.

Once you compare bundled-vs-bundled โ€” which is the fairer matchup โ€” the cold-start gap narrows sharply: OJ 1,315ms versus Vite 1,528ms. The memory numbers, by contrast, stay far apart: OJ 115MB versus Vite bundled 1,751MB. HMR is effectively even between the two.

In production rollout, Lovable reports the numbers that actually matter to its infra: median preview open-to-usable dropped from 17.4s to 8.0s; median sandbox acquisition dropped from 14.5s to 3.0s (a 5x improvement); the dev server uses roughly 6.5x less memory; and it idles at around 400MB.

To Lovable's credit, they disclosed their own caveats โ€” which is what makes the numbers worth reading at all. One comparison included vite-plugin-checker (a TypeScript worker) on the Vite side that OJ simply skips, which weakens the biggest speed comparison but not the memory gap. And when the Node plugin host runs with a real vite.config, OJ still uses less than a third of the memory.

The takeaway: the speed wins are contested and workload-dependent, but the memory win is consistent โ€” and the memory win is the actual point for Lovable's use case.

The real story โ€” AI and the cost of forking open sourceโ€‹

This is the part worth slowing down for.

The framing comes from Sarah Gooding's Socket.dev article, published September 22, 2026, titled: "Lovable's OJ Rewrites Vite's Dev Server in Rust as AI Lowers the Cost of Forking Open Source." You can read it at socket.dev/blog/oj-vite-rust.

Evan You's response on X, verbatim:

Open source dynamics is changing. With the cost of re-implementation collapsing due to AI, we will likely continue to see more "tailored projections" of open source dependencies that are re-implemented under different constraints to optimize for specific use cases (TanStack's redact comes to mind). A possible future is instead of maintainers being overwhelmed by thousands of slop PRs, everyone just maintains their own slop fork. I am honestly not sure if that's good or not, but I think it's quite likely what will happen in a few years.

The phrase to unpack is "tailored projections." OJ is exactly that: a company-specific reimplementation that rebuilt one layer of a general-purpose dependency around Lovable's own infrastructure. It's useful to contrast that with reimplementations led by the original maintainers, or ones that carefully preserve the upstream API:

  • pnpm 12 โ€” a Rust rewrite, but done by pnpm's original maintainers.
  • Rspack โ€” a Rust bundler that deliberately preserves the webpack API.
  • Biome โ€” the Rust successor to Rome, maintained by the community fork.
  • TanStack's "Redact" โ€” You's own cited example: it preserves React's APIs and swaps the runtime underneath.

What's changed is the economics. AI lets a team study an existing implementation, generate compatibility tests against it, translate the code to another language, and close the remaining behavioral gaps far faster than a from-scratch effort used to take. That shifts the incentive away from upstreaming a change and toward simply reimplementing the thing you depend on.

The fragmentation riskโ€‹

Socket's concern, stated plainly: every compatible reimplementation has to independently track upstream behavior, dependency releases, security patches, and edge cases. There's no shared maintenance โ€” each fork carries the full burden on its own.

Concretely: a Vite-compatible dev server does not automatically inherit a fix that lands in Vite's Node dev server. The engineering work moves downstream, to each reimplementation, even as the original project's API becomes more influential and more standard. The API wins; the maintenance fragments.

This connects to trade-offs we've written about before. When forks proliferate, so does the surface area that has to be audited โ€” see our writeup of the TanStack npm supply-chain attack, and the "supply-chain audit difficulty" trade-off we flagged in The Rust Wave Under Your node_modules, where cargo audit and npm audit cover different dependency graphs.

To be fair to OJ: this is not a hostile fork, and it is not a license violation. It's MIT licensed, well-attributed, and it shares Vite's own Rust foundations in Rolldown and Oxc. The debate is about ecosystem dynamics, not legality. And "slop fork" is Evan You's own half-joking phrase โ€” he ends by saying he's honestly not sure whether the trend is good or bad.

What this means for the Aliz stackโ€‹

We recommend Vite, and OJ doesn't change that. It's infrastructure-specific to Lovable's scale, distributed via cargo rather than npm, and tuned around Lovable's own multi-tenant preview constraints โ€” none of which fits a general project. See our Vite page for what we actually run.

There is a positive signal in here, though. The fact that OJ is even possible means Vite's plugin API is stable enough to be a reimplementation target โ€” which is a good sign for Vite's longevity, not a threat to it. We took a shorter first pass at this in our September 14 roundup.

And to close the loop: OJ slots neatly into the broader Rust-rewrite trend without arguing for a "switch to X" conclusion. For the full landscape, see The Rust Wave Under Your node_modules.

Further readingโ€‹

Footnotesโ€‹

  1. See OJ's pinned embedded runtime notes, especially the "Why", "Architecture", and "The plugin host" sections. โ†ฉ