JSPM

  • Created
  • Published
  • Downloads 1072
  • Score
    100M100P100Q106804F
  • License MIT

Vite plugin for React Server Components (RSC)

Package Exports

  • vite-plugin-react-server
  • vite-plugin-react-server/client
  • vite-plugin-react-server/components
  • vite-plugin-react-server/config
  • vite-plugin-react-server/config/createHandlerOptions
  • vite-plugin-react-server/css-loader
  • vite-plugin-react-server/dev-server
  • vite-plugin-react-server/dev-server/cleanupServerAction
  • vite-plugin-react-server/dev-server/configureReactServer
  • vite-plugin-react-server/dev-server/configureRequestHandler
  • vite-plugin-react-server/dev-server/handleServerAction
  • vite-plugin-react-server/dev-server/restartWorker
  • vite-plugin-react-server/directives
  • vite-plugin-react-server/env
  • vite-plugin-react-server/env-loader
  • vite-plugin-react-server/env/plugin
  • vite-plugin-react-server/error
  • vite-plugin-react-server/file-preserver
  • vite-plugin-react-server/helpers
  • vite-plugin-react-server/helpers/handleServerAction
  • vite-plugin-react-server/helpers/resolveStreamElements
  • vite-plugin-react-server/html-worker
  • vite-plugin-react-server/loader
  • vite-plugin-react-server/metrics
  • vite-plugin-react-server/orchestrator
  • vite-plugin-react-server/orchestrator/createPluginOrchestrator
  • vite-plugin-react-server/package.json
  • vite-plugin-react-server/plugin
  • vite-plugin-react-server/react-client
  • vite-plugin-react-server/react-client/plugin
  • vite-plugin-react-server/react-server
  • vite-plugin-react-server/react-server/plugin
  • vite-plugin-react-server/react-static
  • vite-plugin-react-server/react-static/createBuildLoader
  • vite-plugin-react-server/react-static/plugin
  • vite-plugin-react-server/react-static/renderPage
  • vite-plugin-react-server/react-static/rscToHtmlStream
  • vite-plugin-react-server/react-static/temporaryReferences
  • vite-plugin-react-server/register
  • vite-plugin-react-server/rsc-worker
  • vite-plugin-react-server/server
  • vite-plugin-react-server/static
  • vite-plugin-react-server/storybook
  • vite-plugin-react-server/stream
  • vite-plugin-react-server/stream/client
  • vite-plugin-react-server/stream/createFromNodeStream
  • vite-plugin-react-server/stream/createHtmlStream
  • vite-plugin-react-server/stream/createRenderToPipeableStreamHandler
  • vite-plugin-react-server/stream/createRscStream
  • vite-plugin-react-server/stream/handleRscStream
  • vite-plugin-react-server/stream/server
  • vite-plugin-react-server/transformer
  • vite-plugin-react-server/transformer/plugin
  • vite-plugin-react-server/types
  • vite-plugin-react-server/utils
  • vite-plugin-react-server/utils/rsc-client
  • vite-plugin-react-server/vendor
  • vite-plugin-react-server/vendor.client
  • vite-plugin-react-server/vendor.server
  • vite-plugin-react-server/vendor.static
  • vite-plugin-react-server/virtual
  • vite-plugin-react-server/worker

Readme

vite-plugin-react-server

A Vite plugin that transforms React components into native ESM modules with React Server Components support. Build static sites, dynamic servers, or anything in between — your components become portable ESM that works with any HTTP server.

Install

npm install -D vite-plugin-react-server react react-dom

vprs 2.0 runs on stable React 19.2+. The react-server-dom-esm transport ships inside the react-server-loader dependency (installed automatically), so you no longer install a transport or an experimental React build yourself. Upgrading from 1.x? See the migration notes.

Minimal Example

// vite.config.ts
import { defineConfig } from "vite";
import { vitePluginReactServer } from "vite-plugin-react-server";

export default defineConfig({
  plugins: vitePluginReactServer({
    moduleBase: "src",
    Page: "src/page.tsx",
    build: { pages: ["/"] },
  }),
});
// src/page.tsx
export const Page = ({ url }: { url: string }) => <div>Hello from {url}</div>;
# Dev server
npx vite

# Build
NODE_OPTIONS='--conditions react-server' vite build --app

Build Output

dist/
├── static/          # Deployable to any static host
│   ├── index.html   # Pre-rendered HTML
│   └── index.rsc    # RSC payload for client navigation
├── client/          # Client-side ESM modules (for SSR)
└── server/          # Server-side ESM modules (with server actions)

dist/static/ is a complete static site. dist/client/ and dist/server/ are ESM modules you can import in your own Express/Hono/Node server.

Client components

vprs recognises a file as a client module when either of these is true:

  • the filename matches (^|[\/.])client\.[cm]?[jt]sx?$ — i.e. Button.client.tsx, bar.client.mjs, or the standalone basename src/client.tsx / client.tsx, or
  • the file starts with a top-of-file "use client" directive (leading whitespace, line/block comments, and an optional "use strict" prologue are tolerated above it).

Either is sufficient. Substrings like clientUtils.tsx, clientId.ts, or clients.tsx are not treated as client modules, and a "use client" directive placed after real code does not count.

// src/components/Counter.tsx  ← no `.client.` suffix needed
"use client";
import { useState } from "react";
export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

See Getting Started.

Third-party client-component packages

Component libraries like Chakra UI, MUI, Mantine, react-aria, and framer-motion are client-only — their components rely on React context/state and must run inside a client boundary, the same constraint they carry under Next.js's App Router. Use them within a "use client" component (commonly a small provider wrapper); they can't be imported directly into a server component. This isn't a vprs limitation — e.g. Chakra's own Next.js App Router guide requires wrapping ChakraProvider in a 'use client' component.

vprs auto-detects these so they're treated correctly at build start: any package with react in its peerDependencies is classified as a client package (using vitefu.crawlFrameworkPkgs). Two escape hatches if needed:

vitePluginReactServer({
  // Force a package into the list (e.g. one that doesn't peerDep react)
  clientPackages: ["@my/internal-ui"],
  // Skip a detected one (e.g. devDeps Storybook bringing along @storybook/react)
  excludeClientPackages: ["@storybook/react", "@storybook/react-vite"],
});

Storybook

vprs ships a Storybook preset — add one line and your RSC app's components build and render in Storybook:

// .storybook/main.ts
export default {
  framework: { name: "@storybook/react-vite", options: {} },
  addons: ["vite-plugin-react-server/storybook"],
};

It strips the vprs plugin from Storybook's builder, resolves the react-server-dom-esm transport (from react-server-loader), and silences "use client"/"use server" directive noise. See Storybook for details. (Requires vprs ≥ 1.9.0.)

Documentation

Doc What it covers
Getting Started Install → first page → dev server → build → deploy
Storybook One-line Storybook support for vprs apps
Build Output What the build produces, how to use the ESM modules
Configuration All plugin options
CSS Handling Inline/linked CSS, CSS modules, the Css component
Server Actions "use server" directives, form actions, hosting
Examples Static site, dynamic server, server actions, custom routing
Troubleshooting Common errors and fixes
API Reference Exported functions, types, and components

Internals (contributors)

Doc What it covers
Architecture Condition system, module structure, plugin composition
Transformer How "use client" / "use server" directives are processed
Workers RSC and HTML worker threads

Maintenance

Doc What it covers
Releasing Version bumps, publishing, demo updates
React Compatibility Vendored ESM transport, type system

Requirements

  • Node.js 22.0.0+ (the build uses node:fs/promises#glob, which landed in 22)
  • Stable React 19.2+ (react / react-dom at ^19.2.7). As of 2.0 the RSC server APIs vprs relies on (prerenderToNodeStream, the react-server transport exports) are part of stable React, so no experimental build is required. The matching react-server-dom-esm transport is provided by the react-server-loader dependency; experimental React still works if you want the newest RSC features. See React Compatibility.
  • Vite 6+

TypeScript

{
  "compilerOptions": {
    "types": ["vite/client", "vite-plugin-react-server/virtual"]
  }
}

License

MIT