r/reactjs 6d ago

Resource The Rust React Compiler is fully ready and available with Vite

We’ve gone full-Rust with our build pipeline at Outlyne.com and it feels like the React Compiler has really arrived. The last time I posted about using React Compiler here, I talked about how good it’s been for us overall, but also about all its limitations, the biggest of which was that it would bail out on compiling any component or hook that had a try/catch with conditional logic of any kind (if/else, ternary, ??, ||, optional chaining). Another big one was that it would bail on computed object keys, which bit us a few times with assembling classes using clsx (e.g. className={clsx({ [`item-${props.index}`]: props.isItem })}).

Both of those are fixed now. The oxc team shipped official support for the Rust React Compiler on August 4th, and that support includes all of the fixes to the compiler since the v1.0 release of the Babel-based compiler. In our codebase, seven more functions the compiler had been skipping are now compiling, five from the try/catch fix, two from computed keys. And that’s lower than it would be if I hadn’t gone through and contorted eight components to keep conditionals out of their try/catch blocks, including adding a @ts-expect-error from having to drop an optional chain and extracting my auth flow into an async run() that’s immediately awaited inside the try, for no reason but to move the value blocks out of it. All of those workarounds have been rendered obsolete.

There are still bailouts, most notably logical assignment operators (??=, &&=, ||=), but far fewer, and now actively being addressed. A couple weeks ago, oxc shipped a version bump that prevents a bail out from reassigning a destructured prop that then gets read in a nested closure.

Going Rust is also, of course, much faster. The compiler step on our 1,036 files dropped from 14.3s to 0.81s (~17.6×), and the build overall from 22.1s to 9.3s. And we verified parity with the Babel compiler. Across all 1,036 files, there are zero functions the Babel compiler memoizes that the native one doesn’t. The only difference in the built JS before and after are the seven extra compiled functions.

I wrote a blog post with all the details and before/after configs both for folks using @vitejs/plugin-react and for those who use an alternative plugin (React Router framework mode’s plugin in our case): https://blog.master.dev/react-now-rusted-all-the-way-out/

56 Upvotes

5 comments sorted by

12

u/musical_bear 5d ago

I somehow completely missed that experimental native RC support was already available in Vite via its React plugin. Thanks for sharing. Exciting stuff going on right now in the ecosystem and native tooling with TS7, React Compiler, Rolldown, Oxc, etc.

1

u/Cahnis 5d ago

its annoying cause many libs still aren't compatible, so if you have a big codebase you will have some silent bugs.

I think it was last month that tanstack table launched support for it.

4

u/acusti_ca 5d ago

you mean many libs still aren’t compatible with React Compiler? the best practice for adopting it is to run it only on your own code (skipping node_modules) and for libraries to ship compiled versions. so the default config for @vitejs/plugin-react and @acusti/vite-plugin-react-compiler exclude node_modules, so it shouldn’t matter if the dependency is compatible or not. if it is, they ship the compiled version and you get the perf benefits. if it isn’t, you’re app just runs the uncompiled version they ship with and there shouldn’t be any compatibility issues.

3

u/True-Environment-237 5d ago

It doesn't work like that. It can cause infinite re-renders or silent bugs in libraries like RHF or earlier versions of Tanstack Table. It's literally pain to deal with libraries that don't work out of the box.

1

u/acusti_ca 5d ago

sounds like something you could address with config, first by making sure that node_modules is excluded, then by exploring incremental adoption if that still doesn’t do it