| 1 | --- |
| 2 | title: Websites |
| 3 | description: Deploy Vite, Astro, Next.js, Nuxt, React Router, SolidStart, SvelteKit, TanStack Start, Waku, Octane, Foldkit, Vocs, or any static build to Prisma Compute. |
| 4 | sidebar: |
| 5 | label: Overview |
| 6 | order: 1 |
| 7 | --- |
| 8 | |
| 9 | `Prisma.Website` builds your frontend with its own framework and deploys |
| 10 | it to [Prisma Compute](/prisma/compute/apps). The shared |
| 11 | `@alchemy.run/frontend-frameworks` Node targets produce the server and |
| 12 | assets; **Prisma runs that output on Bun**, uploaded as a `tar.gz` |
| 13 | artifact. There is no Docker build, registry, or container image to manage. |
| 14 | |
| 15 | Even fully static sites run a static-file server on Compute. These |
| 16 | resources do not publish an assets-only deployment to a global CDN. |
| 17 | |
| 18 | Omit `project` and the live deployment creates a `Prisma.Project` with |
| 19 | `createDatabase: false`. Pass an existing project to put the site next to |
| 20 | other apps or a database. `alchemy dev` runs the framework's native dev |
| 21 | server instead; the Website creates no Prisma project, database, app, or |
| 22 | domain in that mode. |
| 23 | |
| 24 | ## What's supported |
| 25 | |
| 26 | | Framework | Resource | Guide | |
| 27 | | --- | --- | --- | |
| 28 | | React / Vue / Solid SPA | `Vite` | [Vite](/prisma/frontend/vite) | |
| 29 | | TanStack Start (React & Solid) | `TanStackStart` | [TanStack Start](/prisma/frontend/tanstack-start) | |
| 30 | | React Router | `ReactRouter` | [React Router](/prisma/frontend/react-router) | |
| 31 | | SolidStart | `SolidStart` | [SolidStart](/prisma/frontend/solidstart) | |
| 32 | | Astro SSR & static | `Astro` | [Astro](/prisma/frontend/astro) | |
| 33 | | Next.js | `Nextjs` | [Next.js](/prisma/frontend/nextjs) | |
| 34 | | vinext | `Vinext` | [vinext](/prisma/frontend/vinext) | |
| 35 | | Nuxt | `Nuxt` | [Nuxt](/prisma/frontend/nuxt) | |
| 36 | | SvelteKit | `SvelteKit` | [SvelteKit](/prisma/frontend/sveltekit) | |
| 37 | | Waku | `Waku` | [Waku](/prisma/frontend/waku) | |
| 38 | | OctaneJS | `Octane` | [Octane](/prisma/frontend/octane) | |
| 39 | | Foldkit | `Foldkit` | [Foldkit](/prisma/frontend/foldkit) | |
| 40 | | Vocs | `Vocs` | [Vocs](/prisma/frontend/vocs) | |
| 41 | | Hugo, Zola, or any static generator | `StaticSite` | [Static sites](/prisma/frontend/static-site) | |
| 42 | |
| 43 | ## How to choose |
| 44 | |
| 45 | Use the resource named after your framework. It understands the |
| 46 | framework's config, output layout, build, and dev server. Config files |
| 47 | load natively; deploy-specific overrides belong in option bags such as |
| 48 | `astro`, `nuxt`, `kit`, or `vite`. |
| 49 | |
| 50 | Use `Vite` for client-only SPAs and multi-page HTML apps. SSR frameworks |
| 51 | that use Vite still need their own resources. Use `StaticSite` for a |
| 52 | shell command that emits a directory of files. |
| 53 | |
| 54 | Shared props are `rootDir`, `memo`, `env`, `assets`, `dev`, `domain`, |
| 55 | and `project`. Framework-specific configuration belongs in the named |
| 56 | option bags, not in a Dockerfile or Compute build command. |
| 57 | |
| 58 | The framework guides explain the adapter requirements: Astro and |
| 59 | SvelteKit get injected adapters; Nuxt and SolidStart use the managed |
| 60 | Nitro Node preset; Octane requires the shared `node()` marker adapter. |
| 61 | Next.js runs a normal Next server on Bun, not OpenNext. |
| 62 | |
| 63 | Runtime dependencies are traced from the installed application into the archive; |
| 64 | Prisma does not run a package installation after upload. Native addons must be |
| 65 | built for Prisma's Linux runtime. A deployment from macOS does not cross-compile |
| 66 | native dependencies, so use a compatible Linux build environment for applications |
| 67 | that require them. |
| 68 | |
| 69 | ## Install |
| 70 | |
| 71 | [Set up Prisma credentials](/prisma/setup) for live deployments. Install |
| 72 | the build integration in your frontend project: |
| 73 | |
| 74 | ```sh |
| 75 | bun add -d @alchemy.run/frontend-frameworks @vercel/nft |
| 76 | ``` |
| 77 | |
| 78 | Keep the framework's own dependencies and config. The integration is |
| 79 | loaded from your project at build time; `@vercel/nft` traces the runtime |
| 80 | dependencies for Prisma's artifact. Both are build-time dependencies. |
| 81 | In a monorepo, make the integration available to the frontend project |
| 82 | and the tracing peer available to the deployment workspace. |
| 83 | Each framework guide includes equivalent npm, pnpm, and yarn commands. |
| 84 | |
| 85 | ## Declare a Website |
| 86 | |
| 87 | ```typescript |
| 88 | // alchemy.run.ts |
| 89 | import * as Prisma from "alchemy/Prisma"; |
| 90 | |
| 91 | export const Website = Prisma.Website.Vite("Website", { |
| 92 | rootDir: "./app", |
| 93 | }); |
| 94 | ``` |
| 95 | |
| 96 | `rootDir` defaults to `"."`. Builds are memoized from input content; |
| 97 | `memo` controls which changes trigger a rebuild. |
| 98 | |
| 99 | ## Add it to the Stack |
| 100 | |
| 101 | ```typescript |
| 102 | // alchemy.run.ts |
| 103 | import * as Alchemy from "alchemy"; |
| 104 | import * as Effect from "effect/Effect"; |
| 105 | |
| 106 | export default Alchemy.Stack( |
| 107 | "MyWebsite", |
| 108 | { providers: Prisma.providers(), state: Alchemy.localState() }, |
| 109 | Effect.gen(function* () { |
| 110 | const site = yield* Website; |
| 111 | return { url: site.url }; |
| 112 | }), |
| 113 | ); |
| 114 | ``` |
| 115 | |
| 116 | The result is `{ url, compute, project, domain }`. `site.url` is the |
| 117 | Compute endpoint on deploy and the local dev-server address during |
| 118 | `alchemy dev`; the three backing resources are undefined during native |
| 119 | dev. `domain` is also undefined when no custom hostname is requested. |
| 120 | `Alchemy.localState()` keeps state on this machine; keep that state |
| 121 | available for subsequent deploys and teardown. |
| 122 | |
| 123 | ## Share a project |
| 124 | |
| 125 | Declare a project Effect when several sites should share one: |
| 126 | |
| 127 | ```typescript |
| 128 | export const Site = Prisma.Project("Site", { createDatabase: false }); |
| 129 | ``` |
| 130 | |
| 131 | Pass that Effect to the Website; it is resolved only on the live path: |
| 132 | |
| 133 | ```typescript |
| 134 | export const Website = Prisma.Website.Vite("Website", { project: Site }); |
| 135 | ``` |
| 136 | |
| 137 | You can also pass an existing project ID. The Website does not create |
| 138 | or own a project supplied by ID. |
| 139 | |
| 140 | ## Environment variables |
| 141 | |
| 142 | Top-level `env` is applied before build and dev, and passed to Compute |
| 143 | for the live runtime. It is process environment, not Worker bindings. |
| 144 | Server code reads `process.env`; browser inlining follows the framework's |
| 145 | rules (`VITE_*`, `NEXT_PUBLIC_*`, or `PUBLIC_*`). Never put secrets in |
| 146 | client-visible keys. |
| 147 | |
| 148 | ```typescript |
| 149 | const site = yield* Prisma.Website.Vite("Web", { |
| 150 | env: { VITE_API_URL: api.url }, |
| 151 | }); |
| 152 | ``` |
| 153 | |
| 154 | A Website's automatically created project has no database. For a project |
| 155 | with its default database, Prisma supplies `DATABASE_URL` and |
| 156 | `DATABASE_URL_POOLED` to Compute; leave those system-managed keys out of |
| 157 | `env`. For an independently managed database, use a |
| 158 | [Connection](/prisma/data/connections) and pass its outputs explicitly. |
| 159 | |
| 160 | ## Local development |
| 161 | |
| 162 | ```sh |
| 163 | bun alchemy dev |
| 164 | ``` |
| 165 | |
| 166 | Framework resources run their native dev servers with HMR. `dev` options |
| 167 | configure the local server; the Website does not create cloud resources. |
| 168 | `StaticSite` can run a supplied `dev.command`, or build and serve files |
| 169 | locally. Sibling resources in the Stack retain their own lifecycle. |
| 170 | |
| 171 | Opt a Website into live deployment during dev explicitly: |
| 172 | |
| 173 | ```typescript |
| 174 | export const Website = Prisma.Website.Vite("Website").pipe( |
| 175 | Alchemy.remote(), |
| 176 | ); |
| 177 | ``` |
| 178 | |
| 179 | ## Custom domains |
| 180 | |
| 181 | ```typescript |
| 182 | const site = yield* Prisma.Website.Astro("Web", { |
| 183 | domain: "app.example.com", |
| 184 | }); |
| 185 | ``` |
| 186 | |
| 187 | `domain` creates a [`Prisma.CustomDomain`](/providers/prisma/customdomain) |
| 188 | and changes `site.url` to `https://app.example.com`. Prisma requires the |
| 189 | app to be attached to the project's **current default branch**. |
| 190 | |
| 191 | Domain provisioning is asynchronous. `site.domain` is the created |
| 192 | CustomDomain resource. Configure its `dnsRecords` with your DNS provider |
| 193 | and inspect `status`, `foundryStatus`, and `failureReason` before |
| 194 | sending production traffic. |
| 195 | Alchemy does not automatically create DNS records. Changing an existing |
| 196 | domain's hostname or app is rejected; add a second domain, verify DNS |
| 197 | and TLS, cut traffic over, then remove the old one. See |
| 198 | [Compute custom domains](/prisma/compute/apps#custom-domains). |
| 199 | |
| 200 | ## Where next |
| 201 | |
| 202 | - [Vite](/prisma/frontend/vite) — client builds, SPA routing, and env inlining. |
| 203 | - [Astro](/prisma/frontend/astro) — SSR and fully static sites. |
| 204 | - [Static sites](/prisma/frontend/static-site) — build commands and 404 handling. |
| 205 | - [Compute apps](/prisma/compute/apps) — lower-level builds and Effect-native services. |
| 206 | - [Deployments](/prisma/compute/deployments) — upload, health checks, and promotion. |
| 207 | - [Postgres](/prisma/data/postgres) and [Connections](/prisma/data/connections). |
| 208 | - [Vite example](https://github.com/alchemy-run/alchemy/tree/main/examples/prisma-website-vite). |