A fully functional, from-scratch React framework powered by React Server Components in under 50 lines of code.
Read our blog post for how it works.
Based off the examples in @vitejs/plugin-rsc, and simplified as much as possible.
pnpm install
pnpm start- Want a server router like
ExpressHono? Point the RSC entrypoint to a file likesrc/server.tsx, turn yoursrc/framework/entry.rsc.tsxinto an importable utility to turn JSX into HTML, and add a bunch of routes that render your Server Components. Build your own server router if you want. - Want client-side navigations instead of standard browser navigations? Intercept link clicks and listen to
'popstate'events to hijack browser navigations, and fetch RSC payloads for the next page. Use a convention like anAccept: x-rsc-payloadheader to fetch RSC payloads directly. Or, fetch the HTML and extract the RSC from it, using Base64 instead ofrsc-html-stream. - Want to put your server behind a CDN? Add a
Cache-Control: public, max-age=123header to your responses, and useimport { prerender } from 'react-dom/static'instead ofimport { renderToReadableStream } from 'react-dom/server'. - Want file-based routing, where your routes are determined by the layout of your source code? You can build your own in a few lines with Vite's
import.meta.glob()feature. Use a pattern that matches all the files you want, then map the keys of the object it gives you to a route with each module.for (const [path, loadModule] of Object.entries( import.meta.glob('./pages/**/*.{js,jsx,ts,tsx}'), )) { const pattern = path.replace(/^\.\/pages|\.(js|jsx|ts|tsx)$/g, '').toLowerCase(); addRoute(pattern, async () => { const Component = (await loadModule()).default; return <Component />; }); }
- Want to forego a server and build a static site? You can write a Vite plugin that handles it, based on this example. Any server-rendered site can be turned into a static site by hitting the server with requests and storing the responses to disk. You'll need a way to determine which routes to build up front. Doesn't have to be all-or-nothing---you could make some routes static and some routes dynamic. If you want to get fancy, build a list of routes statically and fall back to the server once those routes aren't fresh enough (known as Incremental Static Regeneration).
- Want to use React's support for Server Functions, Actions, and forms? Pull in a few more lines of boilerplate from this example.