1---
2title: Vite
3description: Deploy a Vite SPA to Prisma Compute with Prisma.Website.Vite — static files served on Bun and Vite's native dev server locally.
4sidebar:
5 order: 2
6---
7
8import { Code, Tabs, TabItem } from "@astrojs/starlight/components";
9
10export const devDeps = "@alchemy.run/frontend-frameworks @vercel/nft";
11
12`Prisma.Website.Vite` runs [Vite](https://vite.dev)'s build and serves
13its output with a generated static-file server on **Bun in Prisma
14Compute**. The Node-target output is uploaded as `tar.gz`, not a Docker
15image. There is no framework SSR handler, but the site still has a
16Compute runtime.
17
18React, Vue, and Solid client SPAs belong here, as do multi-page HTML
19apps. Use the dedicated [Astro](/prisma/frontend/astro),
20[React Router](/prisma/frontend/react-router),
21[SolidStart](/prisma/frontend/solidstart),
22[SvelteKit](/prisma/frontend/sveltekit), or
23[TanStack Start](/prisma/frontend/tanstack-start) resource for SSR.
24
25## Install
26
27The build integration is separate from alchemy. Install it in the Vite
28project; the resource loads its `/vite` and `/vite/node` exports:
29
30<Tabs syncKey="pkgManager">
31 <TabItem label="bun" icon="bun"><Code code={`bun add -d ${devDeps}`} lang="sh" /></TabItem>
32 <TabItem label="npm" icon="npm"><Code code={`npm install -D ${devDeps}`} lang="sh" /></TabItem>
33 <TabItem label="pnpm" icon="pnpm"><Code code={`pnpm add -D ${devDeps}`} lang="sh" /></TabItem>
34 <TabItem label="yarn" icon="seti:yarn"><Code code={`yarn add -D ${devDeps}`} lang="sh" /></TabItem>
35</Tabs>
36
37## Configure Vite
38
39Your `vite.config.*` loads natively, including framework plugins and
40Tailwind. No SSR adapter is needed:
41
42```typescript
43// vite.config.ts
44import { defineConfig } from "vite";
45import react from "@vitejs/plugin-react";
46import tailwindcss from "@tailwindcss/vite";
47
48export default defineConfig({
49 plugins: [react(), tailwindcss()],
50});
51```
52
53## Declare the Website
54
55```typescript
56// alchemy.run.ts
57import * as Prisma from "alchemy/Prisma";
58
59export const Website = Prisma.Website.Vite("Website");
60```
61
62Omit `project` to create a database-less Prisma project on live deploy.
63Pass `project` to use one already declared in your Stack.
64
65## Add it to the Stack
66
67```typescript
68// alchemy.run.ts
69import * as Alchemy from "alchemy";
70import * as Effect from "effect/Effect";
71
72export default Alchemy.Stack(
73 "MyViteSite",
74 { providers: Prisma.providers(), state: Alchemy.localState() },
75 Effect.gen(function* () {
76 const site = yield* Website;
77 return { url: site.url };
78 }),
79);
80```
81
82`site.url` is the Compute endpoint on deploy and Vite's local address
83in dev. See the [Vite example](https://github.com/alchemy-run/alchemy/tree/main/examples/prisma-website-vite).
84
85## Add environment variables
86
87```diff lang="typescript"
88export const Website = Prisma.Website.Vite("Website", {
89+ env: {
90+ VITE_GREETING: "Hello from Alchemy!",
91+ },
92});
93```
94
95`env` is applied before build and dev, and passed to Compute. Vite
96inlines `VITE_*` into the client bundle; other keys are not exposed to
97the browser. Never put a secret in a `VITE_*` key.
98
99## Read the environment
100
101```typescript
102// src/main.ts
103const greeting = import.meta.env.VITE_GREETING ?? "hello";
104```
105
106The browser sees the value captured at build time, not a request-time
107lookup of Compute's environment.
108
109## Single-page vs multi-page
110
111`assets.notFoundHandling` defaults to `"single-page-application"`:
112unmatched paths return `index.html` with status 200 for client routing.
113Use `"404-page"` for multi-page sites with a `404.html`:
114
115```typescript
116export const Website = Prisma.Website.Vite("Docs", {
117 assets: { notFoundHandling: "404-page" },
118});
119```
120
121## Vite configuration
122
123`rootDir` is the directory containing `package.json`, default `"."`.
124The serializable `vite` bag overrides the native config:
125
126```typescript
127export const Website = Prisma.Website.Vite("Website", {
128 rootDir: "./app",
129 vite: { outDir: "build", base: "/docs/" },
130});
131```
132
133`outDir` is relative to `rootDir`; omitted, it follows the file's
134`build.outDir` (Vite defaults to `dist`). `base` sets the public base path.
135
136## Local development
137
138`bun alchemy dev` runs Vite's own server with HMR. The Website creates
139no Prisma project, database, app, or domain. Use `.pipe(Alchemy.remote())`
140to deploy the live path during dev instead.
141
142## Custom domain
143
144```typescript
145export const Website = Prisma.Website.Vite("Website", {
146 domain: "app.example.com",
147});
148```
149
150This creates `Prisma.CustomDomain` and makes `site.url` the HTTPS hostname.
151The app must be on the project's current default branch. Configure the
152returned DNS records yourself and verify provisioning status before
153cutover; see [Custom domains](/prisma/frontend/websites#custom-domains).
154
155## Where next
156
157- [Vite API](/providers/prisma/website/vite).
158- [Websites](/prisma/frontend/websites) — the full framework family.
159- [Compute apps](/prisma/compute/apps) — the underlying runtime.