Lovable Rewrote Vite in Rust... (kind of)
BBetter Stack
Computing/SoftwareSmall Business/StartupsInternet Technology
Transcript
00:00:00You can add one to the counter as there's been another Rust rewrite, this time being the Vite dev
00:00:03server rewritten in Rust by the lovable team, supposedly achieving four times better memory
00:00:07usage and two times quicker cold starts. So let's go ahead and investigate that claim as it might be
00:00:12a little bit misleading, then see if this is something you should switch to in the future,
00:00:15and also what the Vite creator thinks this means for the future of open source.
00:00:24So the project I'm talking about is called OJ, aka Orange Juice, and the idea is that it's one
00:00:29Rust binary that I can point at my existing Vite project and it just runs it. It reads my Vite
00:00:33config, it still runs my existing Vite plugins, but the dev server underneath them, so the file
00:00:38watcher, module graph, hot module reloading, and react fast refresh has all been rewritten in Rust.
00:00:44Funnily enough, this has been done using rolldown and oxy, which V8 itself uses, and void zero
00:00:49maintains. Now to give this a go myself, I built a tan stack app to see if there's any differences
00:00:53between running this with Vite dev or OJ dev. On the surface, it seems they work nearly identically,
00:00:58and everything works like server side rendering, hydration, server functions, fast refresh,
00:01:03dynamic file routes, server routes, tailwind, and asset imports, but digging a bit deeper,
00:01:07I did notice a few minor differences. The first one was on the fast refresh here. If I edit a file,
00:01:13the Vite counter here retains its state, but under OJ, the count resets back to zero,
00:01:17indicating that OJ does a full reload instead of just the component that changed. I actually decided to
00:01:22try and test this same behavior in a plain React app that wasn't tan stack start,
00:01:26and interestingly, it actually seemed to work here. So the same edit here keeps the count the same,
00:01:30and it's not updating the whole page, so it seems to be doing a real hot update. So I don't know why
00:01:35there is a difference there between tan stack start and a plain React app, maybe it's just one of those
00:01:39edge cases that they haven't considered yet. The second difference that I noticed was with the
00:01:42server function. This server function measures the memory of the dev server's whole process tree from
00:01:46inside the app, and on this app under Vite, it's about 380MB across two processes, and under OJ,
00:01:53it's about 320MB also across two processes. So on a small app like this one, it seems the memory
00:01:59usage is roughly the same, with OJ only coming out a tiny bit ahead. So does this mean this project is
00:02:04absolutely useless then? Well, no, because this isn't really what OJ is built for. OJ actually works
00:02:09best on really big apps. When I tested this on a React app with 5000 components, with a script that
00:02:14spawns each dev server code, opens the page in a real Chrome browser, stops the clock when the
00:02:19deepest component is in the DOM, and then samples the memory of that whole process tree, OJ's normal
00:02:24mode is about 1.7 times faster to a painted page than default Vite, and uses about a quarter of the
00:02:29memory. Now to be fair to Vite, Vite 8.1 did ship an experimental feature called bundled dev mode,
00:02:34and if you turn that on, Vite actually gets to 1.18 seconds, so actually a bit quicker than OJ's
00:02:40normal mode, but it doesn't save you on memory. And OJ also has a bundle mode as well, which when used
00:02:45makes it quicker again, at about 0.89 seconds, and it keeps the memory at about a quarter of Vite's.
00:02:51So OJ does seem to have some real memory benefits, and that's kind of the entire reason that Lovable
00:02:55made this project. Lovable previews run a real Vite dev server, and Lovable says they run around a
00:03:00million of those sandboxes a day, and at a scale like that, resource consumption
00:03:04really starts to matter. So Lovable built OJ to get previews that start instantly and stay light,
00:03:09without having to give up the ecosystem that makes the app work in the first place.
00:03:13They also made quite a cool design decision around that use case, aka agents. When editing,
00:03:17a person will typically save one file at a time, but an agent can write 10 or so in a burst,
00:03:22and V would actually treat each one of these saves as an update, but in OJ, the Watcher,
00:03:26module graph, compiler, and hot updates are one pipeline, so a burst is coalesced into one update.
00:03:32There's also a gate that you can switch on where updates are held until the agent itself
00:03:35posts to a flush endpoint, so the preview only applies a finished change. You can see this is
00:03:40a very specific project to solve Lovable's own use cases, and that's what Vite's creator EvanU
00:03:45also acknowledged. His first point in this tweet is that it's a really impressive project that solves
00:03:49Lovable's own problem well, but it's not an entire Vite rewrite. It's just the dev server,
00:03:54and it's also built on Rolldown and Oxy, which void0 maintains, so it's hardly replacing them.
00:04:00The parser, the transformer, and the production bundler in OJ are all void0 ones,
00:04:04Lovable just wrote the server around them. You can essentially think of it as Vite is a node
00:04:08process that drives Rust, whereas OJ is a Rust process driving Rust, with a layer in the middle
00:04:13being JavaScript so it can still talk to Vite's plugin API. Evan then also goes on to point out
00:04:17that OJ gets to be fast because it only supports one shape of app. OJ actually only works with
00:04:22the React apps, aka the ones that Lovable is generating. Vite, on the other hand, has to
00:04:27support every framework, every weird config, every tool built around it, and it deliberately leaves
00:04:31things like ESBuild or the React plugin as separate packages, so you can add them yourself if they're
00:04:36needed. After this, he then also picks out the flaws in the benchmark. The blog's Vite Coldstar
00:04:40includes Vite plugin checker, which runs TypeScript in a background worker, but OJ doesn't actually
00:04:45support that plugin, so it skips that work entirely. He also points out that in Vite, with the bundled dev
00:04:50mode, it is closer to OJ's Coldstart, which is the exact same as what we saw in R numbers, but he does
00:04:55admit that OJ uses significantly less memory, and Vite should probably aim to improve that.
00:04:59Evan's final point in this tweet is the one that I find most interesting. Open source dynamics is
00:05:03changing, the cost of re-implementing something has collapsed because of AI, so we're going to see more
00:05:08of what he calls tailored projections of open source tools, so the same dependency, rebuilt under one
00:05:13component's constraints to fit one use case. He gives Tanstack's redact as another example. A possible
00:05:19future is that instead of maintainers being overwhelmed by thousands of slot PRs, everyone
00:05:23just maintains their own slot fork. He says honestly though, he's not sure if that's a good thing, but he
00:05:28thinks it's quite likely that's what's going to happen in a few years. So on one hand, slot forks are better
00:05:33for maintainers than a load of slot PRs would be, but we do risk fragmentation of the ecosystem. I guess
00:05:39only time is going to tell how this will play out, and what the future of open source is going to be.
00:05:43Overall, this is not really a tool that anyone besides Lovable is going to use, unless you
00:05:47seemingly face the exact same issues of millions of Vite dev servers in sandboxes, and I mean,
00:05:52have you really noticed Vite ever being slow on your own laptop or using too much memory? I personally
00:05:57haven't, but this is definitely still a cool project, and it's cool that they've done this,
00:06:01so let me know in the comments what you think about it. While you're there, subscribe, and as always,
00:06:04see you in the next one.
00:06:09See you in the next one.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video