@rsc-kit/mcp
Version:
An MCP server over what an rsc-kit build decided: the routes, why each one is static or not, and what it costs the browser.
142 lines (107 loc) • 4.31 kB
Markdown
# Quick start
> A running app in one command, or added to a project you already have.
## A new app
```sh
bun create rsc-kit@latest my-app
cd my-app
bun run dev
```
That is it. You get a page, a layout, a client component and a Vite config,
wired together and running. There is no server file — Nitro builds one from the
preset in that config when you build.
It asks a few questions, each with a flag for a script: where it runs, the
React Compiler, Tailwind, oxlint, and which **validation library** you want —
Zod, Valibot or ArkType. That one is asked once because everything schema-shaped
hangs off it: a form's schema, `action.input()`, a page's `searchParams`, and
**typed environment variables**, which it offers next. Say yes and you get
`src/env.ts`:
```ts title="src/env.ts"
export const env = createEnv({
server: {
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
// DATABASE_URL: z.url(),
},
clientPrefix: 'VITE_',
client: {},
// No bare process.env: import.meta.env carries the VITE_ values, and
// the file does not throw in the browser if a client component imports it.
runtimeEnv: { ...(typeof process === 'undefined' ? {} : process.env), ...import.meta.env },
emptyStringAsUndefined: true,
})
```
A missing or malformed variable is refused at startup with its name, not as an
`undefined` three calls later; `env.DATABASE_URL` is typed everywhere it is
read; and a server variable can never reach the browser — a browser-readable
one has to start with `VITE_`. That is [`@t3-oss/env-core`](https://env.t3.gg),
with the schema in whichever library you chose. `.env.example` is written
beside it and is the one that gets committed.
Import `env` from server code. A client component reads its `VITE_` value
from `import.meta.env.VITE_…` directly: importing `src/env.ts` there brings
the validator along to read one string, about 20 kB gzipped for Zod. The
value is still checked, because the server imports `env` when it starts.
```sh
bun create rsc-kit@latest my-app --validation=valibot --env # scripted
```
When you are ready to ship:
```sh
bun run build
bun run start
```
The build prints what it did:
```
○ /
○ (Static) prerendered as static content
1 static
```
Pages marked `○` are **static**: rendered once at build time rather than for
each visitor.
## An app you already have
Already have a project? Add rsc-kit to it:
```sh
bunx rsc-kit@latest init
```
It reads your `package.json`, works out which server you use and where your
source lives, and writes only what is missing. A project with no
`package.json` — a Go or Rust service getting its frontend — is given its
first one. And in an empty directory, or a fresh clone of an empty repository,
there is nothing to add to, so `init` starts a new app right there, leaving the
README alone and adding what the app needs ignored to the `.gitignore`:
```
server hono
source src
react will be added
+ src/app/layout.tsx
+ src/app/page.tsx
+ vite.config.ts
~ package.json — added @rsc-kit/core, react, react-dom, vite, nitro, …
~ scripts — dev, build, start, compile, typecheck
```
No server file. Nitro builds one around the route tree, so the app owns a route
tree and a vite config and nothing in between.
**It never overwrites anything.** If you already have a `vite.config.ts`, it
prints the edit to make instead of replacing work you have done. Running it twice is safe — the second run just tells you what is already
in place.
Then:
```sh
bun install
bun run dev
```
## Add a page
Routes are directories under `src/app`. Create a folder, put a `page.tsx` in
it, and it exists:
```tsx title="src/app/about/page.tsx"
export default function AboutPage() {
return <h1>About</h1>
}
```
```sh
bun run build # the route tree is read at build time
```
## Doing it by hand
If you would rather wire it up yourself — or the CLI cannot reach your
setup — [Installation](/installation) walks through the same result one file at
a time.
## Where next
- [Routing](/guides/routing) — layouts, dynamic segments, parallel slots
- [Server actions](/guides/server-actions) — mutations without an API route
- [Where it runs](/hosts/where-it-runs) — presets, and compiling to a binary