- TypeScript - For type safety and improved developer experience
- TanStack Start - SSR framework with TanStack Router
- Mantine - React component library (
@mantine/core,@mantine/form, charts, dates, schedule, notifications, modals) - Shared UI package - Mantine
MantineProvider, theme, and color-scheme helpers live inpackages/ui - Drizzle - TypeScript-first ORM
- Cloudflare D1 - SQLite-compatible database engine
- Authentication - Better-Auth
- Vite+ - Unified runtime, package, build, lint, format, and test tooling
First, install the dependencies:
vp installThis project uses Cloudflare Workers with D1 and Wrangler for local and remote runtime behavior.
-
Create local Worker secrets:
cp apps/server/.dev.vars.example apps/server/.dev.vars
-
Start the local apps:
vp run dev
Open the local web URL printed by Vite+ in your browser:
- Web app:
http://localhost:3001 - Worker API:
http://localhost:3000 - Wrangler local explorer:
http://localhost:3000/cdn-cgi/local/explorer/
The local explorer shows local D1 and R2 contents while vp run dev is running.
Schema changes are generated with:
vp run db:generateReact web apps in this stack share Mantine setup through packages/ui.
- Tweak the theme in
packages/ui/src/theme.ts - Adjust the provider (color scheme, modals, notifications) in
packages/ui/src/provider.tsx - Edit global styles in
packages/ui/src/styles/globals.css - Mantine PostCSS preset config lives in
packages/ui/postcss.config.cjs
Import shared exports like this:
import { Provider as UIProvider } from "@prive-admin-tanstack/ui/provider"
import { theme } from "@prive-admin-tanstack/ui/theme"
import "@prive-admin-tanstack/ui/globals.css"Mantine components are imported directly from @mantine/* packages in app code:
import { Button } from "@mantine/core"- Format and lint fix:
vp run check
prive-admin-tanstack/
├── apps/
│ └── web/ # Fullstack application (React + TanStack Start)
├── packages/
│ ├── api/ # Shared API layer
│ ├── auth/ # Authentication configuration & logic (Better-Auth)
│ ├── config/ # Shared TS / tooling config
│ ├── db/ # Database schema & queries (Drizzle)
│ ├── env/ # Shared env loading & validation
│ └── ui/ # Mantine provider, theme, and global styles
vp run dev: Start all applications in development modevp run build: Build all applicationsvp run dev:web: Start only the web applicationvp run dev:server: Start only the server Worker with Wranglervp run check-types: Check TypeScript types across all appsvp run db:generate: Generate D1-compatible Drizzle migrationsvp run db:migrate: Run database migrations through Drizzle toolingvp run db:copy:prod-to-dev: Refresh remote dev D1 from remote production D1vp run db:copy:dev-to-local: Refresh local D1 from remote dev D1vp run db:copy:prod-to-local: Refresh local D1 from remote production D1vp run db:studio: Open database studio UIvp run check: Run Oxlint and Oxfmt
Deployments target Cloudflare Workers, D1, and R2. The authoritative deploy
runbook is docs/deploy/cloudflare-d1.md.
- Pull requests to
mainrun source checks and the environment-gated Cloudflare dev deployment. - Pushes to
mainrun the environment-gated Cloudflare production deployment. - Runtime values live in the 1Password vault
prive-admin, in environment-specific items such asprive-admin-cloudflare-dev. - GitHub Actions loads 1Password values after the matching GitHub environment
approval and deploys through
cloudflare/wrangler-action.