UNPKG

@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
# 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