Choosing a target
How the deploy switch works, what each platform supports and how to pick one.
The template builds for four platforms from one configuration. config/adapter.ts resolves the
target from DEPLOY_TARGET, or from the variables each platform sets during a build
(VERCEL=1, NETLIFY=true, WORKERS_CI=1), and falls back to the Node server.
pnpm build:vercel # DEPLOY_TARGET=vercel astro build
pnpm build:cloudflare # DEPLOY_TARGET=cloudflare astro build
pnpm build:netlify # DEPLOY_TARGET=netlify astro build
pnpm build:node # DEPLOY_TARGET=node astro build (default)
Feature matrix#
| Capability | Vercel | Cloudflare | Netlify | Node |
|---|---|---|---|---|
| Static pages | CDN | Workers static assets | CDN | Served by the Node server |
| On-demand routes (auth, dashboard, actions) | Vercel Functions | workerd Worker | Netlify Functions | Same process |
| Runtime | Node 24 | workerd + nodejs_compat |
Node 24 | Node 24 |
| Image optimisation | Vercel Image Optimization | Cloudflare Images binding | Netlify Image CDN | Sharp at build time |
| CSP for prerendered pages | Header | <meta> element |
Header | Header |
| Extra security headers | Build Output config (integration) | public/_headers + middleware |
public/_headers + middleware |
Middleware (SSR) |
| Database | Turso over HTTP | Turso over HTTP | Turso over HTTP | File or Turso |
| Local dev runtime | Node | workerd (pnpm dev:cloudflare) |
Node with Netlify emulation | Node |
The production tables are created the same way on every target: the Migrate database
workflow in GitHub Actions applies the migrations in drizzle/ to the Turso database (see the
database guide). Node hosts can also run
node scripts/migrate.ts next to the server.
Recommendations#
- Vercel is the reference deployment for this repository and needs no configuration.
- Cloudflare runs on-demand code in workerd at the edge; keep Node-only packages out of server routes.
- Netlify is a good fit if you already use Netlify Forms, Blobs or Identity.
- Node is for containers and VPS hosts (Fly.io, Railway, Render, Kubernetes). The included Dockerfile produces a small image with a health check.
What stays identical#
Application code never branches on the platform. The libSQL client picks the correct build
through package export conditions, Better Auth works on standard Request/Response objects,
and Astro handles routing, prerendering and the CSP. Only config/adapter.ts, wrangler.jsonc,
netlify.toml, public/_headers and the Dockerfile are platform-specific.
Verifying before you deploy#
Run the build for your target and, for Node, start the server:
pnpm build:node && pnpm start
CI builds every target on each pull request, so a passing pipeline is a strong signal that the deployment will succeed.