The easiest way to build React apps with server-side rendering.
Build React apps with server-side rendering the way it should be — write a single file, run one command, and everything just works. Powered by Vite with React included out of the box.
Documentation · Getting Started · Examples
npx @lazarv/create-react-serverOr go fully manual — one dependency, one file, one command:
pnpm add @lazarv/react-server// App.jsx
export default function App() {
return <h1>Hello World!</h1>;
}pnpm react-server ./App.jsxThat's it. No config files, no boilerplate, no React installation. Your app is running with full SSR.
Want to try it without installing anything?
npx @lazarv/react-server ./App.jsxworks too.
Most React frameworks require significant setup before you write your first component. @lazarv/react-server takes a different approach — it's as simple as running a script with node, but for React. Start with a single file and scale to a full-featured application with file-system routing, caching, static generation, and multi-runtime deployment as your needs grow.
Built on Vite for instant HMR. Ships with its own React, so your project stays lean. Supports Node.js, Bun, and Deno. Deploys to Vercel, Netlify, Cloudflare, and more with built-in adapters.
| React Server Components | Async server components with streaming SSR — the default rendering model |
| Client Components | "use client" for interactive components with full hook support |
| Server Functions | "use server" with progressive enhancement and form actions |
| File-System Router | Pages, layouts, outlets, API routes, middlewares, error boundaries, loading states |
| Client Navigation | SPA-like navigation with prefetching, rollback, and outlet-scoped updates |
| Caching | Response cache, in-memory cache, "use cache" directive, Unstorage providers |
| Static Export | Full static generation with dynamic route params and compression |
| Partial Pre-Rendering | "use dynamic" / "use static" for mixed static + runtime rendering |
| Live Components | "use live" async generators streamed over WebSocket in real-time |
| Workers | "use worker" for Worker Threads (server) and Web Workers (client) with HMR |
| Micro-Frontends | Compose remote RSC applications with streaming and shadow DOM isolation |
| MCP Server | Model Context Protocol tools, resources, and prompts as HTTP endpoints |
| Markdown & MDX | .md/.mdx as pages with remark/rehype plugins and custom components |
| Middleware Mode | Embed into Express, NestJS, or any connect-compatible server |
| Cluster Mode | Scale across all CPU cores in production |
| Multi-Runtime | Node.js >= 20.10, Bun >= 1.2.9, Deno >= 2.0 |
| Deploy Anywhere | Built-in adapters for Vercel, Netlify, Cloudflare, Bun, and Deno |
Server components are the default. They render on the server, support async/await, and their source code never reaches the client.
export default async function App() {
const data = await fetch("https://api.example.com/data").then((r) => r.json());
return <div>{data.message}</div>;
}Add "use client" to enable interactivity. Components are server-rendered, then hydrated on the client with full React hook and event handler support.
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}"use server" turns any async function into a server-side RPC endpoint. Works as form actions with progressive enhancement — no JavaScript required for basic form submissions.
async function addTodo(formData) {
"use server";
await db.todos.create({ title: formData.get("title") });
}
export default function TodoForm() {
return (
<form action={addTodo}>
<input name="title" />
<button type="submit">Add</button>
</form>
);
}Omit the entrypoint and the framework automatically routes based on your file structure. Every convention you'd expect — and more:
app/
├── layout.jsx # Root layout
├── page.jsx # / (index)
├── about.jsx # /about
├── posts/
│ ├── page.jsx # /posts
│ ├── [id].jsx # /posts/:id (dynamic)
│ └── [...slug].jsx # /posts/* (catch-all)
├── (auth)/
│ └── login.jsx # /login (grouped, no URL segment)
├── @sidebar/
│ └── page.jsx # Parallel outlet
├── loading.jsx # Suspense loading fallback
├── error.jsx # Error boundary
├── (i18n).middleware.mjs # Middleware
└── GET.api.server.mjs # GET /api (REST endpoint)
Configure routing in react-server.config.json:
{
"root": "app",
"page": { "include": ["**/page.tsx"] },
"layout": { "include": ["**/layout.tsx"] }
}Typed routes are auto-generated — include .react-server/**/*.ts in your tsconfig.json for full type safety.
SPA-like transitions with Link, Form, Refresh, and ReactServerComponent. Supports prefetching, error rollback, and outlet-scoped rendering.
import { Link } from "@lazarv/react-server/navigation";
<Link to="/about" prefetch>About</Link>Programmatic navigation via useClient():
import { useClient } from "@lazarv/react-server/client";
const { navigate, prefetch, refresh } = useClient();Multi-layered caching built in at every level:
// Response-level
useResponseCache(30000);
// Data-level with compound keys
const data = await useCache(["posts", id], () => fetchPost(id), 60000);
// Declarative with the "use cache" directive
"use cache; ttl=60; tags=posts";Invalidate on demand with revalidate() and invalidate(). Cache providers are built on Unstorage — use memory, request, local, session, or plug in any custom driver.
Real-time server-to-client streaming with async generators over WebSocket. Each component instance gets its own server-side execution context.
"use live";
export default async function* StockPrice({ symbol }) {
while (true) {
const price = await getPrice(symbol);
yield <span>${price}</span>;
await new Promise((r) => setTimeout(r, 1000));
}
}Mix static and dynamic content at the component level. Static shells are pre-rendered at build time; dynamic parts stream in at runtime.
"use dynamic";
export default async function LiveFeed() {
const items = await fetchLatest();
return <ul>{items.map((i) => <li key={i.id}>{i.title}</li>)}</ul>;
}Offload heavy computation to background threads with "use worker". Runs in Node.js Worker Threads on the server and Web Workers in the browser. Arguments and return values are serialized via the RSC Flight protocol, so you can return React elements directly. HMR is fully supported.
"use worker";
export async function analyze(data) {
return heavyComputation(data);
}Compose independently deployed React Server Component applications. Supports streaming, isolate for shadow DOM encapsulation, shared dependency import maps, and static export.
import { RemoteComponent } from "@lazarv/react-server/remote";
<RemoteComponent src="https://other-app.example.com/widget" defer />Build Model Context Protocol servers with tools, resources, and prompts exposed as streaming HTTP endpoints.
import { createServer, createTool } from "@lazarv/react-server/mcp";
import { z } from "zod";
const echo = createTool("echo", "Echoes input", { message: z.string() }, ({ message }) => message);
export default createServer({ tools: [echo] });react-server [entrypoint] # Development server
react-server build [entrypoint] # Production build
react-server start # Start production serverKey flags: --open, --port, --https, --export, --deploy, --edge, --compression, --adapter <name>, --eval, --sourcemap, --trust-proxy, --build
Auto-detected from react-server.config.{js,mjs,ts,mts,json}. Supports environment-specific variants (.production.config.*, .development.config.*), extension configs (+*.config.*), and runtime-only configs (.runtime.config.*). Your vite.config.* is merged automatically — all Vite plugins work out of the box.
// react-server.config.mjs
export default {
root: "app",
public: "public",
cluster: 4,
prerender: { timeout: 5000 },
cache: {
profiles: { default: { ttl: 60000 } },
},
};Embed into any existing Node.js server:
import { reactServer } from "@lazarv/react-server/dev"; // or /node for production
const { middlewares } = await reactServer();
app.use(middlewares);One command to build and deploy with built-in platform adapters:
react-server build --deploy| Platform | Configuration |
|---|---|
| Vercel | { adapter: "vercel" } |
| Netlify | { adapter: "netlify" } |
| Cloudflare | { adapter: "cloudflare" } |
| Bun | Auto-detected |
| Deno | Auto-detected |
Custom adapters can be built with createAdapter from @lazarv/react-server/adapters/core. Cluster mode scales across all CPU cores with REACT_SERVER_CLUSTER=8 or { cluster: 8 } in config.
Explore the examples to see @lazarv/react-server in action:
git clone https://github.com/lazarv/react-server.git
cd react-server && pnpm install| Example | Command |
|---|---|
| Hello World | pnpm --filter ./examples/hello-world dev |
| Todo App | pnpm --filter ./examples/todo dev --open |
| Photos | pnpm --filter ./examples/photos dev --open |
| Pokemon | pnpm --filter ./examples/pokemon dev --open |
| File Router | pnpm --filter ./examples/file-router dev --open |
| File Upload | pnpm --filter ./examples/file-upload dev --open |
| SPA | pnpm --filter ./examples/spa dev --open |
| SPA Router | pnpm --filter ./examples/spa-router dev --open |
| React Router | pnpm --filter ./examples/react-router dev --open |
| TanStack Router | pnpm --filter ./examples/tanstack-router dev --open |
| React Query | pnpm --filter ./examples/react-query dev --open |
| Mantine UI | pnpm --filter ./examples/mantine dev --open |
| Material UI | pnpm --filter ./examples/mui dev --open |
| Chakra UI | pnpm --filter ./examples/chakra-ui dev --open |
| shadcn/ui | pnpm --filter ./examples/shadcn dev --open |
| Express | pnpm --filter ./examples/express dev |
| NestJS | pnpm --filter ./examples/nestjs start:dev |
| Bun | pnpm --filter ./examples/bun dev |
| Deno | pnpm --filter ./examples/deno dev |
| Partial Pre-Rendering | pnpm --filter ./examples/ppr dev --open |
| Micro-Frontends | pnpm --filter ./examples/remote dev |
| MCP Server | pnpm --filter ./examples/mcp dev |
| Workers | pnpm --filter ./examples/use-worker dev --open |
| Live Monitor | pnpm --filter ./examples/monitor dev --open |
| Session Cookies | pnpm --filter ./examples/session-cookie dev --open |
| Environment Variables | pnpm --filter ./examples/env dev --open |
| React Markdown | pnpm --filter ./examples/react-markdown dev --open |
| React Modal | pnpm --filter ./examples/react-modal dev --open |
| React Syntax Highlighter | pnpm --filter ./examples/react-syntax-highlighter dev --open |
| Module Resolution | pnpm --filter ./examples/module-resolution dev --open |
Contributions are welcome! Check out the contributing guide and the code of conduct.
