Edge-first monorepo boilerplate designed for ultra-fast applications. Built with Turborepo, Hono, Drizzle, Neon, TanStack Start, Astro, Starlight, and Cloudflare Workers.
π Extended Documentation: Visit our Wiki for detailed step-by-step guides on every technology in the stack.
- β‘ Edge-First: Deploy to 300+ locations worldwide with Cloudflare Workers
- π Type-Safe End-to-End: Hono RPC shares types between API and frontend
- ποΈ Serverless Database: Neon Postgres with branching for previews
- π Stateless Auth: Better Auth optimized for edge runtimes
- π¦ Monorepo: Turborepo + pnpm with shared configs and components
- π¨ Shared Design System: Shadcn/ui + Tailwind CSS across all apps
- π§ͺ Testing Ready: Vitest with Cloudflare Workers pool
- π Documentation: Astro Starlight with shared design tokens
βββββββββββββββββββ
β Cloudflare β
β Gateway β
ββββββββββ¬βββββββββ
β
ββββββββββββββββββββΌβββββββββββββββββββ
β β β
ββββββΌβββββ βββββββΌββββββ βββββββΌβββββββ
β API β β Dashboard β β Landing β
β (Hono) β β(TanStack) β β (Astro) β
ββββββ¬βββββ βββββββββββββ ββββββββββββββ
β
ββββββΌβββββ
β Neon β
β(Postgres)β
βββββββββββ
Better Auth lives inside apps/api (following the official Hono integration pattern), not as a separate package. Any app in the monorepo consumes auth via HTTP:
βββββββββββββββ
β Dashboard β ββsignIn.social()βββΊ
β (TanStack) β βββcallbackURLββββββ
βββββββββββββββ
β
fetch /api/auth/get-session (cookie)
β
βΌ
βββββββββββββββ
β API β
β (Hono+Auth) β ββbetterAuth()βββΊ PostgreSQL
βββββββββββββββ
- Client-side:
createAuthClientfrombetter-auth/reactβ typed hooks (useSession,signIn,signOut) - SSR:
getSession()server function forwards cookies to the API β validates on the server - Protected routes:
_protected.tsxlayout withbeforeLoadredirecting to/sign-in - OAuth: Google provider β API handles callback β session cookie set on API domain
End-to-end type safety between API and frontend via @repo/api-types:
apps/api/src/routes.ts ββexport AppTypeβββΊ packages/api-types βββΊ apps/dashboard
β
hc<AppType>("/api")
β
api.message.$get() β autocompletado
apps/api/src/routes.tsexportsAppTypefrom routes (without Cloudflare bindings)packages/api-typesre-exports it for consumption by any frontend- Dashboard uses
hc<AppType>(url)fromhono/clientfor typed fetch calls
| App | Technology | URL Path | Purpose |
|---|---|---|---|
| API | Hono + Workers | /api/* |
Type-safe REST API |
| Dashboard | TanStack Start | /app/* |
Interactive admin interface |
| Landing | Astro | /* |
Marketing page (static) |
| Blog | Astro | /blog/* |
Content marketing |
| Docs | Starlight | /docs/* |
Technical documentation |
| Gateway | Cloudflare Worker | / |
Unified routing |
Note:
wrangler.tomlfiles are not committed (they contain sensitive data). Copy from.example.wrangler.tomlfiles after cloning.cp apps/api/wrangler.toml.example apps/api/wrangler.toml cp apps/gateway/wrangler.toml.example apps/gateway/wrangler.toml
Before starting, make sure you have:
- Node.js 20+ installed (
node --version) - pnpm 9+ installed (
pnpm --version) - A Cloudflare account (free)
- A Neon database (free tier available)
New to these tools? Check our Wiki - Getting Started for detailed setup instructions.
Click "Use this template" on GitHub or clone directly:
git clone https://github.com/LionsTheme/the-edge-stack.git
cd the-edge-stackpnpm installWhat is pnpm? It's a fast, disk space efficient package manager. Learn more in our Wiki - Turborepo & pnpm.
Each app manages its own environment variables. The API is the only one that requires configuration:
cp apps/api/.env.example apps/api/.env
nano apps/api/.envRequired variables:
| Variable | Where to get it | Guide |
|---|---|---|
DATABASE_URL |
Neon Dashboard or local PostgreSQL | Wiki |
BETTER_AUTH_SECRET |
Generate with openssl rand -base64 32 |
Wiki |
BETTER_AUTH_URL |
Your API URL (e.g. http://localhost:8787) |
Wiki |
DASH_URL |
Your frontend URL (e.g. http://localhost:3000) |
Wiki |
GOOGLE_CLIENT_ID |
Google Cloud Console | Wiki |
GOOGLE_CLIENT_SECRET |
Google Cloud Console | Wiki |
π Detailed env setup: See Wiki - Variables de Entorno for step-by-step instructions with screenshots.
# Run migrations
pnpm db:migrate
# (Optional) Generate initial types
pnpm db:generateWhat are migrations? They're versioned SQL files that update your database schema safely. Learn more in Wiki - Drizzle ORM.
pnpm devThis starts all apps in parallel:
| App | URL | Description |
|---|---|---|
| API | http://localhost:8787 | Hono API with RPC |
| Dashboard | http://localhost:3000 | TanStack Start app |
| Landing | http://localhost:4321 | Astro landing page |
| Blog | http://localhost:4322 | Astro blog |
| Docs | http://localhost:4323 | Starlight documentation |
Run from the root directory:
| Command | Description |
|---|---|
pnpm dev |
Start all apps in development mode |
pnpm build |
Build all apps for production |
pnpm db:generate |
Generate Drizzle migrations |
pnpm db:migrate |
Apply database migrations |
pnpm db:studio |
Open Drizzle Studio (GUI) |
pnpm auth:generate |
Regenerate Better Auth Drizzle schema |
pnpm clean |
Clean all build outputs |
Run in a specific app/package:
# Start the API locally
pnpm --filter @repo/api dev
# Start the Dashboard locally
pnpm --filter @repo/dashboard dev
# Build only the UI package
pnpm --filter @repo/ui build
# Regenerate auth schema (after adding plugins/fields)
cd apps/api && pnpm dlx @better-auth/cli@latest generate \
--config ./better-auth.config.ts \
--output ../packages/database/src/auth-schema.tsUser β Cloudflare Gateway β [API | Dashboard | Landing | Blog | Docs]
β
Neon PostgreSQL
1. API Worker
cd apps/api
wrangler deploy2. Gateway Worker
cd apps/gateway
wrangler deploy3. Static Apps
# Landing
cd apps/landing && pnpm build && wrangler pages deploy dist
# Blog
cd apps/blog && pnpm build && wrangler pages deploy dist
# Docs
cd apps/docs && pnpm build && wrangler pages deploy dist4. Dashboard
cd apps/dashboard
pnpm build
wrangler pages deploy .outputπ Detailed deployment guide: See Wiki - Despliegue for production checklists, CI/CD setup, and DNS configuration.
Our Wiki contains detailed guides for every technology:
- Variables de Entorno - Complete env setup guide
- Variables de Entorno Compartidas - Centralized env management
- Turborepo & pnpm - Understanding the monorepo
- Flujo de Desarrollo Local - Local dev with Wrangler & cloudflared
- Service Bindings y Routing - Gateway pattern & CORS avoidance
- Neon PostgreSQL - Database setup
- Drizzle ORM - Database operations
- Migraciones y Entornos - Migration strategy with Neon Branching
- Better Auth - Authentication setup
- Better Auth y Drizzle - Auth + business tables in same DB
- Hono API - API development
- TanStack Start - Dashboard development
- Astro - Landing & blog
- Starlight - Documentation
- Shadcn & Tailwind - UI components
- Cloudflare Workers - Edge computing
- Local Explorer - Local admin interface for debugging
- Consejos y Buenas PrΓ‘cticas - Tips for daily development
- Deployment - Production deployment
- FAQ - Common questions
.env.example- Detailed environment variable explanationsapps/docs/- Full documentation site built with Starlight
the-edge-stack/
βββ apps/
β βββ api/ # Hono API (Cloudflare Worker)
β β βββ src/
β β β βββ index.ts # Entry point + auth middleware
β β β βββ routes.ts # API routes + AppType for RPC
β β β βββ lib/
β β β βββ auth.ts # Better Auth instance (per-request)
β β βββ better-auth.config.ts # CLI config for schema generation
β β βββ .dev.vars # Local secrets (gitignored)
β β βββ wrangler.jsonc
β βββ dashboard/ # TanStack Start SSR app
β β βββ src/
β β β βββ routes/ # File-based routes
β β β β βββ __root.tsx # Root layout
β β β β βββ index.tsx # Public home
β β β β βββ sign-in.tsx # Sign-in page (Google OAuth)
β β β β βββ _protected.tsx # Protected layout (auth check)
β β β β βββ _protected/
β β β β βββ dashboard.tsx # Protected dashboard
β β β βββ lib/
β β β β βββ api.ts # Hono RPC client (type-safe)
β β β β βββ auth-client.ts # Better Auth React client
β β β β βββ auth.functions.ts # SSR session check (server fn)
β β β βββ router.tsx
β β β βββ routeTree.gen.ts
β β βββ vite.config.ts
β βββ landing/ # Astro landing page
β βββ blog/ # Astro blog (MDX)
β βββ docs/ # Starlight documentation
β βββ gateway/ # Cloudflare Gateway Worker
βββ packages/
β βββ database/ # Drizzle schema, migrations, getDb()
β βββ api-types/ # Shared types for Hono RPC (AppType)
β βββ ui/ # Shared UI components (Shadcn)
β βββ tailwind-config/ # Shared Tailwind config
β βββ typescript-config/ # Shared TS configs
βββ tooling/
βββ services/
βββ .github/workflows/ # CI/CD pipelines
βββ turbo.json # Turborepo pipeline
βββ pnpm-workspace.yaml # pnpm workspace config
βββ .env.example # Environment template
The Cloudflare Gateway Worker unifies all apps under a single domain:
| Path | Destination | Technology |
|---|---|---|
/api/* |
API Worker | Hono + Cloudflare Workers |
/app/* |
Dashboard | TanStack Start |
/blog/* |
Blog | Astro |
/docs/* |
Documentation | Starlight |
/* |
Landing page | Astro |
This eliminates CORS issues and simplifies authentication.
Not every project needs all 6 apps. Here's how to trim the boilerplate:
rm -rf apps/blog apps/docsThree files need minor changes:
1. apps/gateway/wrangler.jsonc β remove unused service bindings and routes:
2. apps/gateway/src/types.ts β remove unused bindings from Env:
export interface Env {
API: Fetcher;
DASH: Fetcher;
LANDING: Fetcher;
ROUTES: string;
ASSET_PREFIXES?: string;
}3. apps/gateway/src/router.ts β remove from BINDING_KEYS:
const BINDING_KEYS = new Set<BindingKey>(["API", "DASH", "LANDING"]);TypeScript (BindingKey) keeps everything consistent β if a binding is missing from Env, router.ts won't compile.
pnpm install && pnpm --filter @repo/gateway typecheckmkdir -p apps/shop/srcCreate apps/shop/wrangler.jsonc and apps/shop/package.json as a standard Cloudflare Worker, then register it in three Gateway files:
1. apps/gateway/wrangler.jsonc β add binding + route:
"services": [
{ "binding": "SHOP", "service": "shop" }
]2. apps/gateway/src/types.ts β add to Env:
SHOP: Fetcher;3. apps/gateway/src/router.ts β add to BINDING_KEYS:
"SHOP"TypeScript ensures all three stay in sync. Missing one β compile error.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Hono - Ultralight web framework
- Drizzle ORM - Type-safe SQL
- TanStack - Modern React tools
- Astro - Content-focused web framework
- Starlight - Documentation framework
- Better Auth - Authentication for the edge
- Neon - Serverless PostgreSQL
- Cloudflare Workers - Edge computing platform