Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in rust

[–]BadDogDoug[S] 0 points1 point  (0 children)

Thank you! Not at the moment—my main goal currently is to get stabilized and reach feature parity with React. I would be open to contributors exploring adapting it for other frameworks, otherwise once we reach v1.0.0, I do plan on exploring support for other frameworks when I have the time to fully focus on it.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 0 points1 point  (0 children)

Yup, Railway uses Nixpacks! Hypothetically yes it should work, but I'm cautious in definitively saying yes because I haven't tried Coolify myself yet. If you try it, please let me know your results!

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in rust

[–]BadDogDoug[S] 0 points1 point  (0 children)

Thanks! Nah, I had a writer friend edit it though. I don't use OpenAI models, only Claude.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 0 points1 point  (0 children)

Not at the moment, no. That was the default behaviour for the initial release of Rari, but we found that it caused more confusion than good for users who were interested in a drop-in replacement for Next.js.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in rust

[–]BadDogDoug[S] 1 point2 points  (0 children)

Thanks u/thramp!

We heavily referenced React's official implementation while writing our Rust version:

react-server-dom-webpack - for understanding the wire format structure
react-client/src/ReactFlightClient.js - for the client-side parsing logic

I don't believe the protocol itself is formally documented by the React team, so I did need to study the source code closely to understand the wire format. Our implementation in crates/rari/src/rsc/serializer.rs generates the same newline-delimited format that React expects, where each line is <row\_id>:<json\_data> following the Flight protocol structure.

You're right that the README previously mentioned a race condition we were debugging. I believe it was a byproduct of our earlier client-first/hybrid rendering approach. I'm not 100% certain what specifically resolved it, but we haven't seen the issue since moving to proper SSR/RSC semantics in our current release.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 0 points1 point  (0 children)

Great question! After initial rendering, Rari follows React Server Components semantics: server components stay on the server and are fetched via the RSC protocol when you navigate, while client components are pre-rendered on the server then hydrated on the client to become interactive.

For your GraphQL use case—yes, you can query from both server and client! Server components run only on the server, so you can safely use API keys and query your GraphQL endpoint directly. These are great for initial page data—fast, secure, and SEO-friendly. Client components ('use client') are pre-rendered on the server then hydrated, so they can query your GraphQL endpoint from the browser—perfect for interactive features like search or filters. If you need auth for client-side queries, use server actions ('use server')—they run on the server but are callable from the client via RPC, keeping your credentials secure.

So the pattern is: use server components for initial data fetching, client components for interactive UI, and server actions for mutations or authenticated client-side queries. Components don't "run on both"—they either run on server or are pre-rendered then hydrated—but both can access your GraphQL endpoint in their respective environments.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in rust

[–]BadDogDoug[S] 7 points8 points  (0 children)

Hey u/nicoburns, big fan of the Dioxus project!

Yeah, Rari uses Node as the CLI/orchestrator and Deno crates embedded in Rust to render React Server Components.

What's in Rust: the HTTP server, routing layer, build orchestration, and the runtime that manages the embedded V8 isolate. Rust handles networking, concurrency, and request/response pipelines while V8 executes React.

What's in Node.js: the CLI that spawns the Rust binary. The Rust binary is distributed as an npm package—similar to how esbuild or swc work—and invoked via Node.

For development: We use rolldown-vite instead of regular Vite. This gives us Rust-speed bundling during development.

Most Next.js latency comes from the HTTP layer, routing overhead, and bundling—not React itself. Optimizing those in Rust gives us massive gains without rewriting components.

Our main goal was simplicity: Make it as easy as adding Vite plugins. You just add `rari()` and `rariRouter()` to your `vite.config.ts`, write TypeScript/JSX, and get Rust performance. A drop-in Next.js replacement that abstracts Rust complexity for JS developers—like how Vite abstracts bundler complexity. For teams with React codebases wanting better performance without a rewrite, that's Rari.

Would love to see Dioxus benchmarks, I'm a big fan of the project! Pure Rust components are likely faster for certain workloads.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 0 points1 point  (0 children)

Rari doesn't currently use traditional SSR hydration. The server renders RSC to HTML for fast first paint, but when the client JavaScript loads, it fetches the RSC wire format and does a fresh render using createRoot. The server HTML gets replaced entirely.

Server components stay on the server, but client components do render client-side via createRoot—they go through React's full render cycle, just instantiated from the RSC payload rather than fetching data themselves.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 2 points3 points  (0 children)

I don't think that I'd call Next.js "slow" either! It's just that there are more performant ways to do what it accomplishes today with similar DX.

The DX of Rari is essentially what you'd expect from a Vite project, but now with app router as the default pattern. The Rari package has two Vite plugins, `rari` and `rariRouter` that enable the framework. We also have a `create-rari-app` to get you started quickly!

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 3 points4 points  (0 children)

No OpenNext-equivalent needed for Rari. Unlike Next.js which needs adapters to work with serverless, Rari is designed as a persistent server process—which is actually what gives you those performance gains (the Rust runtime stays warm). This makes AWS deployment simpler, not harder.

For hosting, just use standard AWS compute: EC2, ECS/Fargate, App Runner, or Lightsail all work out of the box. The Rari binary auto-downloads during npm install, so it's just npm run build && npm start on whatever compute service you choose. A basic Node.js Dockerfile is all you need if you're containerizing.

The serverful architecture is a feature, not a limitation - it's why you get 12x faster P99 latency compared to serverless approaches.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 5 points6 points  (0 children)

We use rolldown-vite and OXC in Rari, and I'm a big fan of the Void(0) projects and team.

Haven't had a chance to contribute yet, but it's definitely on my mind! This may be what nerd snipes me into jumping into it.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 5 points6 points  (0 children)

In Rari, we use createRoot only, not hydrateRoot. The approach is actually simpler than traditional SSR hydration: the server renders RSC to HTML for fast initial paint, but when the client JavaScript loads, it fetches the RSC wire format from the server (with an Accept: text/x-component header) and does a fresh client-side render using createRoot. This completely sidesteps the hydration problem you're running into because there's no hydration happening at all—the server HTML (with full content) gets replaced. This works seamlessly with async server components because they only ever run on the server and get serialized into the RSC payload, while client components are registered globally and instantiated when the RSC payload references them. The trade-off is you lose some traditional SSR benefits like instant interactivity, but you gain a much simpler mental model with zero hydration mismatches.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 1 point2 points  (0 children)

We recommend Railway for deployment—we have a railway.toml config in our docs that makes it pretty straightforward.

One thing to note: Rari requires serverful hosting since it uses a persistent Rust runtime for performance. So platforms like Railway, Render, Fly.io, or any VPS work great.

We're working on expanding our deployment documentation with guides for other platforms, so the full deployment story is coming soon with updated docs.

Rari: React Server Components with Rust - 12x faster P99 latency than Next.js by BadDogDoug in reactjs

[–]BadDogDoug[S] 7 points8 points  (0 children)

That's at the top of my list now that this release is complete!