Skip to content

RSC Overview

The @veloxts/web package enables React Server Components (RSC) with Vinxi and React 19, providing a unified full-stack architecture where server and client code coexist seamlessly.

React Server Components allow components to render on the server by default, with the ability to mark specific components as client-side when needed:

// Server Component (default) - runs on server, no JS sent to client
async function UserProfile({ userId }: { userId: string }) {
const user = await db.user.findUniqueOrThrow({ where: { id: userId } });
return <div>{user.name}</div>;
}
// Client Component - interactive, runs in browser
'use client';
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
Browser Request
Vinxi (Meta-framework)
┌─────────────────────────────────────┐
│ React Server Components │
│ ├── Server rendering (RSC) │
│ ├── Server Actions → Procedures │
│ └── Client hydration │
└─────────────────────────────────────┘
VeloxTS Procedures (Business Logic)
Database (Prisma)
Terminal window
# Full-stack RSC
npx create-velox-app my-app --rsc
cd my-app
pnpm dev
# RSC with authentication
npx create-velox-app my-app --rsc-auth
FeatureDescription
Server ComponentsComponents render on server by default—zero client JS
Server ActionsType-safe mutations that call procedures directly
File-based RoutingPages in app/pages/ map to URL routes
Nested LayoutsCompose layouts with shared UI and data loading
StreamingProgressive page loading with Suspense boundaries
Type SafetyEnd-to-end types from database to UI
my-app/
├── app/
│ ├── pages/ # File-based routes
│ │ ├── index.tsx # → /
│ │ ├── about.tsx # → /about
│ │ └── users/
│ │ ├── index.tsx # → /users
│ │ └── [id].tsx # → /users/:id
│ ├── layouts/ # Layout components
│ │ └── root.tsx # Root layout (wraps all pages)
│ ├── actions/ # Server actions
│ │ └── users.ts # User mutations
│ └── components/ # Shared components
├── api/
│ ├── procedures/ # VeloxTS procedures
│ └── index.ts # API entry point
├── prisma/
│ └── schema.prisma # Database schema
└── app.config.ts # Vinxi configuration
AspectRSC (--rsc, --rsc-auth)SPA (--default, --auth)
RenderingServer-first, streams HTMLClient-side rendering
Data FetchingServer Components + ActionsAPI calls from browser
Bundle SizeMinimal client JSFull React app in browser
SEOExcellent (server-rendered)Requires SSR/SSG setup
InteractivityOpt-in with 'use client'Everything is interactive
Best ForContent sites, dashboardsSPAs, mobile-first apps

Server Actions connect your React components to database operations with validation:

app/actions/users.ts
'use server';
import { validated } from '@veloxts/web/server';
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
});
export const createUser = validated(CreateUserSchema, async (input, ctx) => {
// input is typed: { name: string; email: string }
const { db } = await import('@/api/database');
const user = await db.user.create({ data: input });
return { success: true, user };
});
// app/pages/users/new.tsx
import { createUser } from '@/app/actions/users';
export default function NewUserPage() {
return (
<form action={createUser}>
<input name="name" required />
<input name="email" type="email" required />
<button type="submit">Create User</button>
</form>
);
}