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.

77 lines (59 loc) • 3.04 kB
# Running on Bun > What is different when the runtime is Bun — and what only looks like it is. Bun is the default host, and most of an app never notices. What follows is what an app *does* notice, collected from real ports: the framework's part first, then the things that will look like the framework's fault and are not. ## Vite runs on Bun too `vite` is a bin with a Node shebang, so `bun run dev` alone starts Vite — and with it the dev server, the build and the prerender — under **Node**. An app that imports `bun`, `bun:sqlite` or a Bun-only driver then fails at the first render with `Cannot find package 'bun'`, in a project that just said it was a Bun app. The scaffold's scripts run Vite on Bun's runtime, and an existing app should too: ```json title="package.json" { "scripts": { "dev": "bun --bun vite", "build": "bun --bun vite build", "start": "bun .output/server/index.mjs" } } ``` `createTestApp()` runs that `build` script, so a test builds on the same runtime the server ships on. ## Native dependencies stay outside the bundle A package with a native binary — `sharp`, `bcrypt`, `better-sqlite3`, `@prisma/client` — cannot be rolled into a server bundle: the build succeeds and the server cannot load its own binary. The usual ones are left external by default, and Nitro traces each into `.output/server/node_modules` with its binaries, so the deployment is still one directory. For one that is not on the list: ```ts title="vite.config.ts" rscKit({ serverExternalPackages: ['@acme/native-thing'] }) ``` The same applies on Node; it is only more visible on Bun because the scaffold builds there. ## A build machine without the secrets The build prerenders pages, which runs the app, which runs `instrumentation.ts`, which imports `env.ts`. A build machine without the production variables sets `SKIP_ENV_VALIDATION=1`; the server that runs the build validates at startup regardless. And never `NODE_ENV` in a `.env` — Vite honours it, and `NODE_ENV=development` turns `vite build` into a build that cannot render; [the build refuses it](/installation#environment-variables) and names the line. ## Not the framework's, but you will meet them - **`bun test` reads `.env`.** Bun loads the package's `.env` into every test run. A test that must not see the app's variables — or must see only the ones it sets — runs with `bun test --env-file=/dev/null`. - **Stripe's SDK is async-only on Bun.** `stripe.webhooks.constructEvent()` throws on every call because Bun has no synchronous WebCrypto; `constructEventAsync()` is the same check, awaited. - **`pg` puts SQLSTATE in `errno`.** Bun's Postgres driver reports the five-character SQLSTATE (`23505`) where Node's `pg` reports it as `code`. Match on both if the app runs on both. - **Bun's `setTimeout(0)` is a real millisecond**, as Node's is. Nothing to do; worth knowing when a test counts ticks. --- Everything else — presets, deployment, the single binary — is on [Where it runs](/hosts/where-it-runs).