Skip to content

TanStack Start

Prisma.Website.TanStackStart builds TanStack Start for React or Solid through your project’s Vite pipeline. The shared Node target wraps its fetch handler as an HTTP server; SSR and client assets run on Bun in Prisma Compute from a tar.gz upload. There is no Docker image or registry.

Install the build-time integration; the resource loads /tanstack-start and /tanstack-start/node from your project:

Terminal window
bun add -d @alchemy.run/frontend-frameworks @vercel/nft

Keep the framework plugin and normal Vite plugins. For React:

vite.config.ts
import tailwindcss from "@tailwindcss/vite";
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [tailwindcss(), tanstackStart(), viteReact()],
});

The integration drives builder.buildApp() and makes the SSR bundle self-contained. No deployment adapter is required.

alchemy.run.ts
import * as Prisma from "alchemy/Prisma";
export const Website = Prisma.Website.TanStackStart("Website", {
rootDir: "./app",
});

Omit rootDir for an app at .. Live deploy creates a database-less Prisma project if project is omitted; pass an existing project to share it with other apps.

alchemy.run.ts
import * as Alchemy from "alchemy";
import * as Effect from "effect/Effect";
export default Alchemy.Stack(
"MyTanStackSite",
{ providers: Prisma.providers(), state: Alchemy.localState() },
Effect.gen(function* () {
const site = yield* Website;
return { url: site.url };
}),
);

Client assets are served first; misses go to SSR, server routes, or server functions. site.url is the Compute endpoint on deploy.

export const Website = Prisma.Website.TanStackStart("Website", {
rootDir: "./app",
env: { API_BASE: "https://api.example.com" },
});

env is applied before build and dev and passed to Compute. Vite inlines VITE_* values into the browser bundle; keep secrets out of those keys. Sibling outputs can feed env inside the Stack generator.

src/routes/index.tsx
import { createServerFn } from "@tanstack/react-start";
const getApiBase = createServerFn({ method: "GET" }).handler(() => ({
apiBase: process.env.API_BASE ?? "unset",
}));

Server functions run on Bun and read process.env.

src/routes/api.hello.ts
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/hello")({
server: {
handlers: {
GET: () => new Response(process.env.API_BASE ?? "unset"),
},
},
});

Server routes use the same process environment.

Your vite.config.ts is the build configuration. Keep Vite’s default output directory, dist; the integration reads dist/server and dist/client. Static files are served by Compute, not deployed as an independent CDN site.

bun alchemy dev starts TanStack Start’s native Vite server with HMR and creates no Prisma resources for the Website. Opt into live deployment during dev explicitly:

export const Website = Prisma.Website.TanStackStart("Website").pipe(
Alchemy.remote(),
);
const site = yield* Prisma.Website.TanStackStart("Web", {
domain: "app.example.com",
});

Prisma.CustomDomain requires the app to be on the current default branch. Configure returned DNS records yourself and verify status before cutover; see Custom domains.