Edge-First SaaS Boilerplates 2026
TL;DR
Edge-first SaaS means your code runs in 300+ locations worldwide — millisecond latency for every user, zero cold starts, and infrastructure costs that scale to near-zero at low traffic. The tradeoff: you're constrained by the Workers runtime (no Node.js APIs, limited duration) and the D1 SQLite database is still maturing. For global B2B SaaS, API products, and developer tools, the edge stack is increasingly compelling. For monolithic CRUD apps with complex SQL, traditional cloud is still better.
Key Takeaways
- Cloudflare Workers free tier: 100k requests/day with zero cold starts — best free tier in serverless
- D1 (SQLite) is Cloudflare's edge database — free tier is generous, production readiness is solid as of 2026
- Hono is the dominant micro-framework for Workers (and Bun/Deno/Node — runs anywhere)
- KV (key-value store) and R2 (object storage) complete the edge storage stack at low cost
- No full-stack boilerplate like ShipFast exists yet — you're assembling from primitives
- Best for: API products, global B2B SaaS, developer tools, webhooks at scale
The Edge Stack Components
Compute: Cloudflare Workers (JavaScript/TypeScript, V8 isolates)
Database: D1 (SQLite at the edge, replicated globally)
Cache/State: KV (eventually consistent, global)
Storage: R2 (S3-compatible, zero egress fees)
Auth: Clerk + Workers, or DIY with KV sessions
Queue: Queues (Workers Queue for async jobs)
Email: Resend or Mailchannels (Workers integration)
AI: Workers AI (GPU inference at the edge)
Pricing snapshot (2026):
| Service | Free Tier | Paid |
|---|---|---|
| Workers | 100k req/day | $5/month + $0.50/M requests |
| D1 | 5M reads, 100k writes/day | $0.001/M reads |
| KV | 100k reads, 1k writes/day | $0.50/M reads |
| R2 | 10GB storage | $0.015/GB |
| Queues | 1M operations/month | $0.40/M ops |
Why Edge for SaaS?
Traditional SaaS deploys to a single region (us-east-1 is the joke). Users in Singapore, London, or São Paulo experience 200-400ms latency before your code even starts running. Edge-first inverts this: your code runs in the datacenter closest to the user.
Practical impact:
| Architecture | User in Singapore (origin: US) |
|---|---|
| Traditional (Vercel, Railway) | 180-300ms p95 |
| Edge-first (Cloudflare Workers) | 15-50ms p95 |
For API products, developer tools, and B2B SaaS where speed is a differentiator, this matters.
Hono — The Edge-Native Framework
Hono is the framework of choice for Cloudflare Workers SaaS. It's ultra-lightweight (~14kB), runs on any JavaScript runtime (Workers, Bun, Deno, Node), and has a Next.js-style API for SSR.
// worker.ts — complete Hono app on Cloudflare Workers
import { Hono } from "hono";
import { clerkMiddleware, getAuth } from "@hono/clerk-auth";
import { cors } from "hono/cors";
type Env = {
DB: D1Database;
KV: KVNamespace;
CLERK_SECRET_KEY: string;
};
const app = new Hono<{ Bindings: Env }>();
app.use("*", cors());
app.use("/api/*", clerkMiddleware());
// D1 query
app.get("/api/projects", async (c) => {
const { userId } = getAuth(c);
if (!userId) return c.json({ error: "Unauthorized" }, 401);
const { results } = await c.env.DB.prepare(
"SELECT * FROM projects WHERE user_id = ? ORDER BY created_at DESC"
)
.bind(userId)
.all();
return c.json({ projects: results });
});
// KV caching
app.get("/api/config/:key", async (c) => {
const cached = await c.env.KV.get(c.req.param("key"));
if (cached) return c.json(JSON.parse(cached));
const config = await getConfig(c.req.param("key"));
await c.env.KV.put(c.req.param("key"), JSON.stringify(config), { expirationTtl: 3600 });
return c.json(config);
});
export default app;
Notable Edge-First SaaS Starters
1. hono-workers-saas (Community)
The most complete free edge SaaS starter. Stack:
- Hono on Cloudflare Workers
- D1 (SQLite via Drizzle ORM)
- Clerk authentication
- Stripe billing
- React frontend (served from Workers)
- KV for session caching
npm create cloudflare@latest my-saas -- --template=hono
2. create-cloudflare + Hono (Official)
Cloudflare's official starter, then add Hono:
# Official Cloudflare starter
npm create cloudflare@latest my-app -- --type=hello-world
# Add Hono
npm install hono @hono/zod-validator zod
# Add D1
wrangler d1 create my-saas-db
3. Remix + Cloudflare Workers
Remix has first-class Cloudflare Workers support:
npx create-remix@latest --template cloudflare-workers
This gives you Remix's nested routing and data loading on the edge. Pair with D1 via Drizzle for a complete stack.
4. Next.js + Cloudflare (via next-on-pages)
npm create cloudflare@latest my-next-app -- --framework=next
Limited: Next.js on Workers uses the Edge Runtime, which doesn't support all Node.js APIs. Better as a static/hybrid than full server app.
5. workers-sdk SaaS Template
wrangler generate my-saas cloudflare/workers-sdk/templates/worker-typescript
Minimal TypeScript starter, no framework. Good for API products where you want full control.
D1 Database Patterns
D1 is SQLite, which means:
- ✅ Fast reads (SQLite is remarkably fast)
- ✅ ACID transactions
- ✅ Standard SQL syntax
- ❌ No complex JSON aggregations (limited JSONEach etc)
- ❌ Single-writer model (no concurrent writes from multiple processes)
Drizzle + D1
// db/schema.ts
import { sqliteTable, text, integer, real } from "drizzle-orm/sqlite-core";
export const subscriptions = sqliteTable("subscriptions", {
id: text("id").primaryKey(),
userId: text("user_id").notNull(),
stripeSubscriptionId: text("stripe_subscription_id"),
status: text("status").notNull().default("free"),
currentPeriodEnd: integer("current_period_end"),
});
// worker.ts
import { drizzle } from "drizzle-orm/d1";
app.get("/api/subscription", async (c) => {
const db = drizzle(c.env.DB);
const { userId } = getAuth(c);
const [subscription] = await db
.select()
.from(subscriptions)
.where(eq(subscriptions.userId, userId!));
return c.json(subscription ?? { status: "free" });
});
Migration workflow
# Create migration
npx drizzle-kit generate
# Apply to local D1
wrangler d1 execute my-saas-db --local --file=./drizzle/migrations/0001_add_subscriptions.sql
# Apply to production D1
wrangler d1 execute my-saas-db --file=./drizzle/migrations/0001_add_subscriptions.sql
Authentication on the Edge
Clerk (Easiest)
import { clerkMiddleware, getAuth } from "@hono/clerk-auth";
app.use("*", clerkMiddleware());
app.get("/api/me", async (c) => {
const { userId } = getAuth(c);
if (!userId) return c.json({ error: "Unauthorized" }, 401);
return c.json({ userId });
});
wrangler.toml:
[vars]
CLERK_SECRET_KEY = "sk_..."
CLERK_PUBLISHABLE_KEY = "pk_..."
DIY Session Auth (No third party)
// Store sessions in KV
async function createSession(userId: string, kv: KVNamespace) {
const sessionId = crypto.randomUUID();
await kv.put(`session:${sessionId}`, userId, { expirationTtl: 86400 * 7 });
return sessionId;
}
async function getSession(sessionId: string, kv: KVNamespace) {
return kv.get(`session:${sessionId}`);
}
KV sessions are globally consistent within ~60 seconds — fine for most SaaS auth flows.
Billing at the Edge
Stripe works fine from Workers — it's just HTTPS requests. The main consideration is webhook handling:
// Stripe webhook handler on Workers
app.post("/webhooks/stripe", async (c) => {
const signature = c.req.header("stripe-signature")!;
const body = await c.req.text();
const event = await stripe.webhooks.constructEventAsync(
body,
signature,
c.env.STRIPE_WEBHOOK_SECRET
);
if (event.type === "customer.subscription.updated") {
const sub = event.data.object;
const db = drizzle(c.env.DB);
await db
.update(subscriptions)
.set({ status: sub.status, currentPeriodEnd: sub.current_period_end })
.where(eq(subscriptions.stripeSubscriptionId, sub.id));
}
return c.json({ received: true });
});
Edge-First vs Traditional: Honest Comparison
| Consideration | Edge-First | Traditional (Vercel/Railway) |
|---|---|---|
| Global latency | ✅ 15-50ms everywhere | ⚠️ 50-300ms outside origin region |
| Cold starts | ✅ None (V8 isolates) | ⚠️ 200-2000ms (varies) |
| Node.js APIs | ❌ Not available | ✅ Full Node.js |
| Database options | 🟡 D1 (SQLite) | ✅ Postgres, MySQL, MongoDB |
| Ecosystem maturity | 🟡 Growing | ✅ Mature |
| Boilerplate options | 🟡 Few | ✅ Many (ShipFast, Makerkit, etc.) |
| Max execution time | 30s (CPU time) | Unlimited (Vercel Pro) |
| Cost at scale | ✅ Very low | ✅ Reasonable |
| Cost at zero scale | ✅ Free | ✅ Free (most have free tiers) |
Bottom line: Edge-first is a specialized choice. Pick it when global latency matters to your users or when you're building an API product where sub-50ms response times are a selling point.
Recommended Stack: Hono + D1 + Clerk + Stripe
For a production-ready edge SaaS in 2026:
# Scaffold
npm create cloudflare@latest my-saas -- --type=hello-world
# Install dependencies
npm install hono @hono/clerk-auth drizzle-orm stripe resend zod
# Create D1 database
wrangler d1 create my-saas-db
# Set up R2 bucket (file uploads)
wrangler r2 bucket create my-saas-uploads
wrangler.toml:
name = "my-saas"
main = "src/worker.ts"
compatibility_date = "2025-09-01"
[[d1_databases]]
binding = "DB"
database_name = "my-saas-db"
database_id = "..."
[[kv_namespaces]]
binding = "KV"
id = "..."
[[r2_buckets]]
binding = "FILES"
bucket_name = "my-saas-uploads"
Total infrastructure cost at launch: $0/month (well within Workers + D1 + KV free tiers).
Deploying and Testing Your Edge SaaS
Local development for Cloudflare Workers is handled by Wrangler's dev command, which runs a local Workers runtime that mimics the production environment closely:
# Start local dev server with D1 local mode
wrangler dev --local
# Run migrations against the local D1:
wrangler d1 execute my-saas-db --local --file=./drizzle/migrations/0001_init.sql
Testing in CI uses @cloudflare/vitest-pool-workers for unit tests that run in a Workers-compatible sandbox. Deployment to production is one command: wrangler deploy. Cloudflare keeps the last 10 versions and rollback takes under 30 seconds from the dashboard.
Limitations You Will Hit in Production
The edge-first model creates constraints that become apparent once you move beyond prototype stage. None of these are dealbreakers, but they require deliberate architectural choices.
CPU time limits. Workers have a 30ms CPU time limit on the free plan and a 30-second CPU time limit on paid plans. The limit is CPU time, not wall-clock time — I/O (network requests, D1 queries) does not count. Offload heavy compute to Cloudflare Queues: the Worker enqueues a job, a separate Queue Consumer Worker processes it with more generous limits.
D1 write throughput. SQLite's single-writer architecture means D1 cannot handle the write throughput of a horizontally scaled PostgreSQL cluster. For most SaaS products this is not a concern — D1 handles hundreds of writes per second, exceeding the write rate of nearly all early-stage products. If you're building a high-frequency event ingestion pipeline, route writes through a Cloudflare Queue to serialize them rather than hitting D1 directly from the request handler.
No native stateful WebSocket rooms. Workers support WebSockets, but Cloudflare Durable Objects are required for stateful rooms (collaborative editing, multi-player features). Durable Objects are available but have their own pricing and programming model. For real-time subscriptions without Durable Objects, polling with a 2–5 second interval is often acceptable and much simpler to implement.
Third-party SDK compatibility. Most Node.js SDKs work in Workers, but those that use Node.js-specific APIs (fs, child_process, native buffers) do not. AWS SDK v3, Stripe SDK, Resend, and most HTTP-based APIs work without issues. Standard PostgreSQL TCP drivers do not — they require a Workers-compatible HTTP adapter such as Neon's serverless driver.
Edge SaaS vs the Boilerplate Ecosystem
One honest limitation of the edge-first approach: the mature SaaS boilerplate ecosystem — ShipFast, Makerkit, Supastarter, Open SaaS — is built around Next.js on Vercel with PostgreSQL. None of these ship with Cloudflare Workers as the primary deployment target.
This means an edge-first SaaS founder assembles more from primitives than someone using a polished boilerplate. The upside is full control and lower costs. The downside is that auth flows, billing webhook handling, multi-tenant patterns, and email integration need to be assembled rather than configured. For teams wanting edge performance without full assembly work, hybrid approaches use Cloudflare for the compute layer while keeping a Next.js frontend on Vercel.
For the full spectrum from edge-native to full-featured Next.js starters, the best SaaS boilerplates guide helps calibrate how much you are building versus buying. Teams evaluating Next.js as their primary framework should read the Next.js SaaS tech stack guide for the standard deployment and infrastructure picture. And for open-source starting points that can be adapted to edge deployment, the best free open-source SaaS boilerplates guide covers starters with permissive licenses suitable for modification.
The practical recommendation for 2026: if your product has a clear requirement for global-latency API responses or Cloudflare Workers is your preferred infrastructure for cost reasons, start edge-first with Hono, D1, and Drizzle. If you are building a standard SaaS with no strong latency requirements for global users, start with a mature Next.js boilerplate and consider adding a Cloudflare Workers layer for specific routes later if benchmarks justify it. The edge stack is powerful, but the ecosystem maturity gap with Next.js is real and the assembly cost is higher. The right time to go edge-first is when the product requirements justify the added effort, not because edge architecture is technically interesting.
Production Patterns for Edge SaaS in 2026
Teams shipping edge-first SaaS in production have converged on several patterns that address the ecosystem gaps discussed above.
Authentication without NextAuth. Auth.js and Lucia don't run natively on Workers (they have Node.js dependencies). The three practical alternatives: Cloudflare Access (free up to 50 users, enterprise-grade JWT-based auth), better-auth with the Cloudflare adapter (community-supported), or rolling JWT authentication with Cloudflare KV for session storage. Of these, Cloudflare Access is the most production-proven but requires users to log in via a Cloudflare-managed portal — not suitable for products with consumer sign-up flows. Custom JWT with KV is the most flexible and the approach used in most production Workers apps with standard email/password or OAuth flows.
Payments with Stripe. Stripe's Node.js SDK works on Workers via the official stripe npm package (which uses the Fetch API internally). Webhook signature verification works correctly in the Workers environment. The main difference from a Next.js deployment: Workers functions have no persistent file system, so Stripe webhook secrets must come from environment variables (set in the Cloudflare Dashboard or via Wrangler secrets), not from files. This is a minor deployment consideration, not a fundamental limitation.
Email sending. Resend, Postmark, and Mailgun all work via their HTTP APIs from Workers. Workers also has native Cloudflare Email Routing integration for receiving email — useful for products that need inbound email parsing (support tickets, contact forms). Standard transactional email sending is straightforward and well-documented for the Workers environment.
Background jobs. Workers Cron Triggers handle scheduled tasks natively — no third-party job queue needed for simple cron use cases. For more complex job workflows (retry logic, fan-out processing, large batch operations), Cloudflare Queues provides a native job queue that integrates directly with Workers. Inngest and Trigger.dev also support Workers deployment for teams that want the observability and step-function features those tools provide.
Database migrations. Drizzle ORM with the D1 HTTP driver handles schema migrations via drizzle-kit push or the Wrangler D1 execute command. Unlike the local Wrangler development server (which runs SQLite locally), production D1 runs on Cloudflare's globally distributed SQLite — a meaningful architectural difference. Migrations must be run explicitly before deploying schema changes, and D1's SQLite dialect means features like full JSON column support behave differently than PostgreSQL JSON columns in Neon or Supabase.
The edge-first approach works well in production for SaaS products where the latency benefits matter and the team is comfortable with the assembly work. For most SaaS products without strict latency requirements across a global user base, the mature Next.js ecosystem — with its richer boilerplate selection, larger community, and more complete tooling — remains the faster path to a fully-featured product.
Methodology
- Analyzed Cloudflare pricing pages, D1 documentation, and Workers limits as of March 2026
- Tested Hono on Workers with D1 and Drizzle in local development
- Reviewed community starters on GitHub (GitHub search + Cloudflare Discord)
- Compared Workers runtime constraints vs Node.js environment
- Reviewed Remix, Next.js, and Hono on Workers deployment guides
Compare all Cloudflare Workers and edge-first starters on StarterPick.
The edge-first SaaS stack is not for everyone — but for the right product profile (globally distributed user base, latency-sensitive API endpoints, cost-conscious architecture), it delivers advantages that server-rendered Next.js deployments can't match at equivalent price points. The Cloudflare Workers platform's continued investment in D1, R2, Queues, and AI features makes it an increasingly complete foundation for production SaaS in 2026.
Check out this boilerplate
View Hono + Cloudflare Workerson StarterPick →