1---
2title: Waku
3description: Deploy Waku to Prisma Compute with Prisma.Website.Waku — React Server Components and static pages on Bun, with Waku's native dev server locally.
4sidebar:
5 order: 13
6---
7
8import { Code, Tabs, TabItem } from "@astrojs/starlight/components";
9
10export const devDeps = "@alchemy.run/frontend-frameworks @vercel/nft";
11
12`Prisma.Website.Waku` builds a [Waku](https://waku.gg) React Server
13Components app with the shared Node target. Its RSC server, client
14assets, and SSG pages run on **Bun in Prisma Compute** after a `tar.gz`
15upload. There is no Docker image or registry.
16
17## Install
18
19Install the build-time integration in your project; the resource loads
20its `/waku` and `/waku/node` exports:
21
22<Tabs syncKey="pkgManager">
23 <TabItem label="bun" icon="bun"><Code code={`bun add -d ${devDeps}`} lang="sh" /></TabItem>
24 <TabItem label="npm" icon="npm"><Code code={`npm install -D ${devDeps}`} lang="sh" /></TabItem>
25 <TabItem label="pnpm" icon="pnpm"><Code code={`pnpm add -D ${devDeps}`} lang="sh" /></TabItem>
26 <TabItem label="yarn" icon="seti:yarn"><Code code={`yarn add -D ${devDeps}`} lang="sh" /></TabItem>
27</Tabs>
28
29## Configure Waku
30
31A fresh project needs no deployment config. If present,
32`waku.config.ts` loads natively, including plugins in its `vite` field:
33
34```typescript
35// waku.config.ts
36import tailwindcss from "@tailwindcss/vite";
37import { defineConfig } from "waku/config";
38
39export default defineConfig({
40 basePath: "/",
41 vite: { plugins: [tailwindcss()] },
42});
43```
44
45Waku does not load a standalone `vite.config.ts`. Put Vite config in
46`waku.config.ts`. Don't set `unstable_adapter`: the shared Node target
47owns it and rejects a conflicting adapter.
48
49The resource's `waku` bag overrides `srcDir`, `distDir`, or `basePath`
50from the file:
51
52```typescript
53export const Website = Prisma.Website.Waku("Website", {
54 waku: { basePath: "/docs/" },
55});
56```
57
58## Declare the Website
59
60```typescript
61// alchemy.run.ts
62import * as Prisma from "alchemy/Prisma";
63
64export const Website = Prisma.Website.Waku("Website");
65```
66
67`rootDir` defaults to `"."`. A live deployment creates a database-less
68Prisma project if `project` is omitted; pass an existing project to
69share it with other apps.
70
71## Add it to the Stack
72
73```typescript
74// alchemy.run.ts
75import * as Alchemy from "alchemy";
76import * as Effect from "effect/Effect";
77
78export default Alchemy.Stack(
79 "MyWakuSite",
80 { providers: Prisma.providers(), state: Alchemy.localState() },
81 Effect.gen(function* () {
82 const site = yield* Website;
83 return { url: site.url };
84 }),
85);
86```
87
88Pages configured with `render: "static"` are generated at build time
89and served at extensionless URLs such as `/about`. Dynamic pages and
90API routes run in Compute. `site.url` is the live endpoint.
91
92## Add environment variables
93
94```diff lang="typescript"
95export const Website = Prisma.Website.Waku("Website", {
96+ env: {
97+ GREETING: "Hello from Alchemy!",
98+ API_BASE: "https://api.example.com",
99+ },
100});
101```
102
103`env` accepts strings or `Redacted` values. It is applied before build
104and dev, and passed to Compute. Client inlining follows the framework's
105rules; do not expose secrets in public keys.
106
107## Read the environment in server code
108
109```typescript
110// src/pages/index.tsx
111export default async function HomePage() {
112 return <h1>{process.env.GREETING ?? "hello"}</h1>;
113}
114
115export const getConfig = async () => ({ render: "dynamic" }) as const;
116```
117
118The RSC server runs on Bun. Server components and API routes can read
119`process.env`; static pages capture those values during prerendering.
120
121## Local dev
122
123`bun alchemy dev` runs Waku's own server with HMR instead of deploying.
124The Website creates no Prisma resources. Opt into the live path with:
125
126```typescript
127export const Website = Prisma.Website.Waku("Website").pipe(
128 Alchemy.remote(),
129);
130```
131
132## Custom domain
133
134```typescript
135const site = yield* Prisma.Website.Waku("Web", {
136 domain: "app.example.com",
137});
138```
139
140`domain` creates `Prisma.CustomDomain` and makes `site.url` the HTTPS
141hostname. The app must be on the project's current default branch.
142Configure returned DNS records yourself and verify status before cutover;
143see [Custom domains](/prisma/frontend/websites#custom-domains).
144
145## Where next
146
147- [Waku API](/providers/prisma/website/waku).
148- [Waku example](https://github.com/alchemy-run/alchemy/tree/main/examples/prisma-website-waku).
149- [Websites](/prisma/frontend/websites) and [Compute apps](/prisma/compute/apps).