---
name: Bun React SSR
description: Use when building server-rendered React with Bun, including streaming SSR, hydration, renderToString, or custom SSR without a framework.
version: 1.0.0
---
# Bun React SSR
Build custom server-rendered React applications with Bun.
## Quick Start
```bash
# Initialize project
mkdir my-ssr-app && cd my-ssr-app
bun init
# Install dependencies
bun add react react-dom
bun add -D @types/react @types/react-dom
```
## Basic SSR Setup
### Server Entry
```typescript
// src/server.tsx
import { renderToString } from "react-dom/server";
import App from "./App";
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
// Serve static files
if (url.pathname.startsWith("/static/")) {
const file = Bun.file(`./public${url.pathname}`);
if (await file.exists()) {
return new Response(file);
}
}
// Render React app
const html = renderToString();
return new Response(
`
);
}
```
## Build Client Bundle
```typescript
// build.ts
await Bun.build({
entrypoints: ["./src/client.tsx"],
outdir: "./public/static",
target: "browser",
minify: true,
splitting: true,
});
```
```bash
# Build client
bun run build.ts
# Start server
bun run src/server.tsx
```
## Streaming SSR
```tsx
// src/server-streaming.tsx
import { renderToReadableStream } from "react-dom/server";
import App from "./App";
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
const stream = await renderToReadableStream(
,
{
bootstrapScripts: ["/static/client.js"],
onError(error) {
console.error(error);
},
}
);
// Wait for shell to be ready (Suspense boundaries)
await stream.allReady;
return new Response(stream, {
headers: { "Content-Type": "text/html" },
});
},
});
```
### With Suspense
```tsx
// src/App.tsx
import { Suspense } from "react";
function SlowComponent() {
// This would be a data fetching component
return
Loaded!
;
}
export default function App({ url }: { url: string }) {
return (
Streaming SSR
Fast Shell
Loading...
}>
);
}
```
## Data Fetching
### Server-Side Data
```tsx
// src/server.tsx
import { renderToString } from "react-dom/server";
import { Database } from "bun:sqlite";
import App from "./App";
const db = new Database("data.sqlite");
Bun.serve({
async fetch(req) {
const url = new URL(req.url);
// Fetch data server-side
const users = db.query("SELECT * FROM users").all();
const html = renderToString(
);
return new Response(
`
SSR