---
title: "Introduction"
description: "React Server Components as a Vite plugin, deployed wherever you like."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.rsc-kit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

`rsc-kit` is a Vite plugin that gives you React Server Components. You write
pages, layouts and server actions the way you would in the Next.js App Router;
it renders them, streams the HTML, and turns links into navigations that replace
only the part of the page that changed.

It brings no build system of its own — it is a Vite plugin — and it does not
write a server for you either. [Nitro](https://nitro.build) builds one around
your route tree, so where an app runs is a preset: Bun, Node, a Cloudflare
Worker, Vercel, Netlify, Deno.

## What an app looks like

```text
src/app/
  layout.tsx         the document — <html>, <head>, <body>
  loading.tsx        Suspense fallback for everything below
  page.tsx           GET /
  posts/
[slug]/
  page.tsx       GET /posts/:slug
  @modal/
default.tsx      a parallel slot, empty until something fills it
```

Nothing registers those files. The plugin reads the directory at build time and
generates the entry that knows about them.

```tsx title="src/app/posts/[slug]/page.tsx"
import { findPost } from '../../../data'

export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params
  const post = await findPost(slug)

  if (!post) return <h1>No such post</h1>

  return (
<article>
  <h1>{post.title}</h1>
  <p>{post.body}</p>
</article>
  )
}
```

A server component is an ordinary async function. It imports its data module
directly, and neither the module nor its secrets reach the browser.

## What you get

- **Streaming, not waterfalls** — The shell paints before the data resolves. Suspense boundaries fill in as
they finish, in whatever order they finish.
- **Navigations that keep the page** — A navigation sends the layout chain it already has, and the server answers
with only the part that changed. Scroll, focus and half-typed forms survive.
- **Parallel routes and interception** — `@slot` directories render alongside the page. `(.)folder` opens a route as
a modal over the page you were on, and as a real page on refresh.
- **Server actions** — `"use server"` makes an async function callable from a client component.
The body never ships; the call becomes one POST.
- **Queries, without an endpoint** — `query()` marks a read. It travels as a GET, so it can be cached and
prefetched — and reads that happen together leave as one request.
- **Frozen where it can be** — Pages that ask for nothing dynamic are rendered at build time. Pages that do
get their shell frozen and their data streamed.
- **An export target** — The same app can build to a directory of files and be served by anything —
including a CDN with no origin at all.

## Where it runs

You do not write a server. [Nitro](https://nitro.build) builds one from your
route tree, and where it runs is one line in your Vite config:

```ts title="vite.config.ts"
nitro({ preset: 'bun' })
```

Swap the preset for `node`, `cloudflare_module`, `vercel`, `netlify` or `deno`
and the same app deploys there instead. The build produces a `.output`
directory; nothing else changes.

## What it is not

> **No data layer, no CSS pipeline, no dev server of its own**
>
> The build runs your project's Vite config, so Tailwind, PostCSS and the rest
> are configured the way they are in any Vite app. Data access is an import.
> There is no `getServerSideProps` equivalent, and no request context to learn.

## Where to go next

- **Getting started** — [Build and deploy your first app →](/getting-started)
- **Routing** — [Pages, layouts, slots and navigation →](/guides/routing)
- **How it works** — [What happens between a request and a page →](/reference/how-it-works)

Source: https://docs.rsc-kit.dev/introduction/index.mdx
