Foldkit
Foldkit is an Elm-architecture frontend framework
built on Effect. Its apps are client-only Vite projects, so
Prisma.Website.Foldkit is Vite with SPA
fallback to index.html. Deep links boot the app and its router takes over.
The client build and generated server are uploaded as tar.gz and
served on Bun in Prisma Compute. There is no Foldkit SSR handler,
but the deployment still runs a Compute static-file server; no Docker
image or registry is needed.
Install
Section titled “Install”Install the build-time integration; the resource loads /vite and
/vite/node from your frontend project:
bun add -d @alchemy.run/frontend-frameworks @vercel/nftnpm install -D @alchemy.run/frontend-frameworks @vercel/nftpnpm add -D @alchemy.run/frontend-frameworks @vercel/nftyarn add -D @alchemy.run/frontend-frameworks @vercel/nftConfigure Vite
Section titled “Configure Vite”Keep Foldkit’s Vite setup and your existing plugins:
import { foldkit } from "@foldkit/vite-plugin";import tailwindcss from "@tailwindcss/vite";import { defineConfig } from "vite";
export default defineConfig({ plugins: [foldkit(), tailwindcss()], optimizeDeps: { entries: ["src/entry.ts"] },});Declare the Website
Section titled “Declare the Website”import * as Prisma from "alchemy/Prisma";
export const Website = Prisma.Website.Foldkit("Website", { rootDir: "applications/web",});Omit rootDir for an app at .. Omit project to create a
database-less Prisma project on live deploy, or pass an existing project.
Add it to the Stack
Section titled “Add it to the Stack”import * as Alchemy from "alchemy";import * as Effect from "effect/Effect";
export default Alchemy.Stack( "MyFoldkitSite", { providers: Prisma.providers(), state: Alchemy.localState() }, Effect.gen(function* () { const site = yield* Website; return { url: site.url }; }),);site.url is the Compute endpoint on deploy and Vite’s local URL in dev.
Add environment variables
Section titled “Add environment variables”export const Website = Prisma.Website.Foldkit("Website", { rootDir: "applications/web", env: { VITE_API_URL: "https://api.example.com", },});env is applied before build and dev, and passed to Compute. The SPA
only sees values Vite inlines at build time. VITE_* keys are public,
so never put secrets in them.
Read the environment
Section titled “Read the environment”/// <reference types="vite/client" />
interface ImportMetaEnv { readonly VITE_API_URL: string;}This declares the client-visible key for TypeScript.
const apiUrl = import.meta.env.VITE_API_URL;Vite replaces the lookup with the build-time value.
Deep links
Section titled “Deep links”assets.notFoundHandling defaults to "single-page-application".
A path like /counter/42 returns index.html with status 200, letting
Foldkit’s client router resolve it. For real 404 responses instead:
export const Website = Prisma.Website.Foldkit("Website", { assets: { notFoundHandling: "404-page" },});Local dev
Section titled “Local dev”bun alchemy dev runs Vite with Foldkit HMR and devtools. The Website
creates no Prisma resources. .pipe(Alchemy.remote()) selects the live
path during dev. Pin the local address when running several apps:
export const Website = Prisma.Website.Foldkit("Website", { dev: { host: "127.0.0.1", port: 5180, strictPort: true },});Custom domain
Section titled “Custom domain”const site = yield* Prisma.Website.Foldkit("Web", { domain: "app.example.com",});This creates Prisma.CustomDomain; the app must be on the project’s
current default branch. Configure the returned DNS records yourself
and verify status before cutover. See
Custom domains.
Where next
Section titled “Where next”- Foldkit API.
- Foldkit example.
- Vite, Websites, and Compute apps.