Package Exports
- vite-plugin-react-server
- vite-plugin-react-server/check-react-version
- 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/patch
- 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-dom-esm
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.development
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-client.browser.production
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-client.node.development
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-client.node.production
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-server.node.development
- vite-plugin-react-server/react-server-dom-esm/cjs/react-server-dom-esm-server.node.production
- vite-plugin-react-server/react-server-dom-esm/client
- vite-plugin-react-server/react-server-dom-esm/client.browser
- vite-plugin-react-server/react-server-dom-esm/client.node
- vite-plugin-react-server/react-server-dom-esm/esm/react-server-dom-esm-client.browser.development
- vite-plugin-react-server/react-server-dom-esm/esm/react-server-dom-esm-client.browser.production
- vite-plugin-react-server/react-server-dom-esm/esm/react-server-dom-esm-node-loader.production
- vite-plugin-react-server/react-server-dom-esm/esm/react-server-dom-esm-server
- vite-plugin-react-server/react-server-dom-esm/esm/react-server-dom-esm-server.node
- vite-plugin-react-server/react-server-dom-esm/index
- vite-plugin-react-server/react-server-dom-esm/server
- vite-plugin-react-server/react-server-dom-esm/server.node
- vite-plugin-react-server/react-server-dom-esm/static
- vite-plugin-react-server/react-server-dom-esm/static.node
- 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@experimental react-dom@experimentalMinimal 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 --appBuild 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
Mark a client component with a top-of-file "use client" directive. The
.client. filename suffix is optional — a first-party module that starts
with "use client" is detected, hosted, and emitted as a client chunk in the
static (--app) build, so you can import it directly into a server component:
// 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>;
}Detection is by directive position (top of file, the same rule React enforces),
not by a substring match. The .client. convention still works as a visual
marker. 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 vendored
react-server-dom-esm, 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 23.7.0+
- React experimental channel (
react@experimental/react-dom@experimental). Stable React 19.x is not yet supported — the vendoredreact-server-dom-esmreadsTaintRegistryPendingRequestsfrom React's server internals, and the taint registry is only exposed on the experimental channel today. See React Compatibility for the full story; stable support is tracked separately and is gated on upstream React landing the taint API in the stable build. - Vite 6+
TypeScript
{
"compilerOptions": {
"types": ["vite/client", "vite-plugin-react-server/virtual"]
}
}License
MIT