An opinionated, batteries-included full-stack SaaS starter for Cloudflare.
Next.js, D1, Drizzle, Auth.js and Tailwind — already wired together, fully typesafe, and deployable to Cloudflare's global network in one command. MIT licensed, no attribution required.
| Runtime | Next.js App Router on Cloudflare Workers via @cloudflare/next-on-pages |
| Database | Cloudflare D1 (serverless SQLite) with Drizzle ORM, migrations wired up |
| Auth | Auth.js v5 with the Drizzle adapter and a Google provider configured |
| UI | Tailwind CSS + shadcn/ui, with a server-resolved light/dark theme (no flash) |
| Tooling | Bun, Wrangler, generated CloudflareEnv types, one-command setup |
The landing page is a complete, production-quality marketing site you can keep or replace.
bun create kitedeploy/template app
cd app && bun install
# Provisions D1, writes bindings, generates types, seeds .dev.vars
bun run setup
bun run dev # develop locally against real bindings
bun run deploy # build with next-on-pages and ship to Cloudflare| Command | Does |
|---|---|
bun run setup |
Authenticates Wrangler, creates a D1 database, writes the binding into wrangler.toml, prompts for auth secrets, generates typed env definitions |
bun run dev |
Local dev server |
bun run preview |
Build and preview with Wrangler against real bindings |
bun run deploy |
Build with next-on-pages and deploy |
bun run db:generate |
Generate SQL migrations from the Drizzle schema |
bun run db:migrate:dev |
Apply migrations to the local D1 instance |
bun run db:migrate:prod |
Apply migrations to the remote D1 instance |
bun run db:studio:dev |
Drizzle Studio against local D1 |
Secrets live in .dev.vars locally (git-ignored) and in Worker secrets in production.
bun run setup creates this for you; .dev.vars.example documents what's needed.
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
AUTH_SECRET=
.env.example covers the separate variables drizzle-kit needs to run migrations against
your production database.
- Routes that touch Cloudflare bindings run on the edge runtime — that's what
export const runtime = "edge"is doing. Everything else is ordinary Next.js. - D1 is designed for horizontal scale-out across many small databases. Per-user or per-tenant databases are a supported pattern, not a workaround.
- Adding auth providers is a few lines each in
src/server/auth.ts. The Drizzle adapter already owns the user, session and account tables.
MIT. Fork it, rename it, ship it commercially.
Originally derived from Dhravya/cloudflare-saas-stack, with a rebuilt UI and design system.
Part of KiteDeploy — where your app goes when it's real.