Preparing for Deployment
Houdini is deployed through platform adapters passed to the Vite plugin. For the most part, the adapter takes care of the details: it wires up a server that renders your app on the platform you’re targeting. Install your adapter and pass it to the Houdini plugin in your Vite config:
import { houdini } from 'houdini/vite'import adapter from 'houdini-adapter-auto'
export default { plugins: [houdini({ adapter })]}The following adapters are available:
| Adapter | Target |
|---|---|
houdini-adapter-auto | An adapter for deploying your Houdini application according to the build environment |
houdini-adapter-cloudflare | The adapter for deploying your Houdini application to Cloudflare Pages |
houdini-adapter-node | The adapter for deploying your Houdini application as a standalone node server |
houdini-adapter-static | The adapter for deploying your Houdini application as a single-page application without a server component |
Single-Page Applications
If you want to build a traditional single-page application with no server-side rendering, use houdini-adapter-static. The build output lands in dist/ with a static index.html at the root, ready to deploy to any static host.
import { houdini } from 'houdini/vite'import adapter from 'houdini-adapter-static'
export default { plugins: [houdini({ adapter })]}One constraint: the static adapter is incompatible with local APIs. Since there’s no server to resolve queries against, your app must point at an external GraphQL endpoint.
Cloudflare
houdini-adapter-cloudflare builds a Worker (worker.tsworker.js) alongside a build/assets directory of client files. Point your wrangler static-assets binding at the client assets directory, not the build root:
main = "build/worker.js"
[assets]directory = "build/assets"binding = "ASSETS"The Worker bundle carries your server-only configuration (the session signing keys from src/server/+config.tssrc/server/+config.js, plus anything else you put there). It runs as the Worker; it must never also be served as a static file. Binding ASSETS at a directory that contains worker.tsworker.js would publish those secrets over HTTP.
Keeping secrets out of what you serve
Everything under src/server (including src/server/+config.tssrc/server/+config.js) compiles into the server bundle only, so the session signing keys never land in houdini.config or the client bundle. The one rule to honor at deploy time is the same on every platform: serve only the client assets directory as static files, and never expose the server bundle (the Cloudflare Worker, or the Node server’s build/ssr) over your static-file route. The built-in Node adapter already confines its static route to build/assets for you; on platforms where you configure static serving yourself, scope it to the client assets directory.
Scaling to multiple instances
Most of deployment is identical whether you run one server or many. Two things only start to matter once requests can land on more than one instance (load-balanced, autoscaled, or serverless), and both live in src/server/+config.tssrc/server/+config.js. On a single long-lived server you can skip this.
Set auth.sessionKeys explicitly. Without them, Houdini signs sessions with a random key generated per process. That’s fine on one server, but across instances the keys won’t match (a cookie signed by one instance won’t verify on another), and they don’t survive a restart or redeploy. Point them at a secret your instances share, usually from the environment:
import type { ServerConfigFile } from 'houdini'
export default { auth: { // pass more than one to rotate: the first signs, the rest still verify sessionKeys: [process.env.SESSION_SECRET!], },} satisfies ServerConfigFileGive auth.consumedTokenStore a shared store. The single-use check that stops @session token replays is kept in memory by default, so one instance can’t see a token another already honored. Point it at something shared (a few lines of Redis). It’s a one-method interface that expires its own entries, so there’s nothing to maintain; see the authentication guide for the shape.
Even on a single instance, configuring sessionKeys is good practice so sessions survive a redeploy rather than resetting with the process.