A TanStack Start template built with TanStack Start, featuring modern full-stack TypeScript architecture with end-to-end type safety, authentication, real-time data, and a production-ready chat experience.
After registering and logging in, you can explore these demo features:
- 📊 Dashboard - View real-time statistics and metrics with live data updates via Convex subscriptions
- 💬 Chat - Multi-threaded AI chat with real-time persistence, personas, and OpenRouter responses via the Vercel AI SDK
- 👥 Admin Dashboard - Full admin interface with:
- User management (view, edit, delete users)
- System statistics and analytics
- Data management tools
- 👤 Profile - User profile management and settings
- File-based routing with TanStack Router for intuitive page organization
- Server functions for type-safe API endpoints and data fetching
- Progressive enhancement - works without JavaScript, enhances with it
- Parallel data loading with route loaders and Convex real-time queries
- Better Auth integration with secure session management
- Role-based access control (Admin/User permissions)
- Route guards for protected pages and server functions
- Audit logging for complete action tracking
- Password reset and email verification flows
- shadcn/ui components - 20+ pre-built, accessible UI primitives
- TailwindCSS for responsive, utility-first styling
- Dark/Light mode support ready
- Form handling with TanStack React Form and Zod validation
- Loading states and error boundaries for smooth UX
- Convex for real-time, serverless database operations
- Type-safe queries and mutations with automatic client generation
- Real-time subscriptions for live data updates
- Automatic scaling and global distribution
- Integrated authentication with Better Auth
- End-to-end type safety from database to UI
- Hot reloading and fast development server
- Oxc for fast linting, formatting, and type-aware analysis
- Performance monitoring hooks for development insights
- Automatic cache management with Convex real-time subscriptions
- Email integration with Resend for transactional emails
- Error monitoring with Sentry integration (optional)
- Performance monitoring and session replay
- SEO optimization utilities
- Export functionality for data management
- Virtualized components for handling large datasets
- One-click deployment to Netlify with database provisioning
- Environment management with secure secret handling
- Build optimization for production performance
- Automatic SSL and CDN through Netlify
Create your repository from this template
Clone your new repository:
git clone https://github.com/YOUR_USERNAME/YOUR_REPO_NAME.git cd YOUR_REPO_NAMERun the automated setup:
pnpm run setup:dev
This automated script will guide you through local development setup, including:
- Interactive Convex project creation
- Development environment configuration (URLs and environment variables)
- Optional authenticated Playwright E2E setup via
pnpm run setup:e2e
Then start the app with either:
pnpm devOr, if you need the Docker-backed local runtime path:
pnpm run dev:dockerAutomated Production Setup (Recommended):
# After completing local development setup
pnpm run setup:prodWhat happens automatically:
- ✅ Checks for git remote repository
- ✅ Deploys Convex functions to production
- ✅ Prompts for optional
RESEND_API_KEYon Convex production - ✅ Verifies
JWKSon Convex production after deploy and triespnpm run convex:jwks:syncwhen missing - ✅ Optionally sets
VITE_CONVEX_URLon Netlify (production context) - ✅ Guides GitHub Actions deploy environments and Netlify hooks
🎉 Result: Your app will be live with authentication, database, and real-time features!
Ongoing hygiene: See docs/DEPLOY_ENVIRONMENT.md for Convex cruft removal (pnpm run convex:env:hygiene), .env.local drift checks (pnpm run convex:env:verify), and Resend/JWKS notes.
Command map: See docs/SCRIPT_COMMAND_MAP.md for the quickest “intent → command” lookup.
pnpm testpnpm test:e2ePlaywright uses the real local app at http://127.0.0.1:3000 and starts a frontend-only server with pnpm test:e2e:server. It reuses your configured Convex deployment from env instead of starting convex dev.
Authenticated E2E relies on a gated test-only auth helper. The easiest setup path is:
pnpm setup:e2eThat command updates .env.local with deterministic E2E principals and syncs the required gate vars to your current Convex deployment automatically. If you prefer to manage the values manually, add these values to .env.local before running authenticated suites:
APP_DEPLOYMENT_ENV=development
ENABLE_E2E_TEST_AUTH=true
E2E_TEST_SECRET=replace-with-a-shared-secret
E2E_USER_EMAIL=e2e-user@local.test
E2E_USER_PASSWORD=replace-with-a-deterministic-password
E2E_ADMIN_EMAIL=e2e-admin@local.test
E2E_ADMIN_PASSWORD=replace-with-a-deterministic-passwordpnpm run setup:e2e writes the deterministic credentials locally and syncs the Convex gate vars. Principal provisioning now happens outside the app runtime: run pnpm run e2e:provision manually, or let the browser tooling auto-provision on first use before it saves playwright/.auth/user.json and playwright/.auth/admin.json.
Because the frontend test server reuses your configured Convex development deployment, that deployment must also have:
APP_DEPLOYMENT_ENV=development
ENABLE_E2E_TEST_AUTH=true
E2E_TEST_SECRET=the-same-shared-secretpnpm setup:e2e handles that sync for the current development deployment. Never enable these vars on preview, staging, or production deployments.
For AI-driven browser automation, prefer the test-only agent auth endpoint instead of filling the login form:
POST /api/test/agent-authx-e2e-test-secret: <E2E_TEST_SECRET>Content-Type: application/json
{
"principal": "user",
"redirectTo": "/app"
}Run that request from the same browser session your automation tool will continue using. On success, the endpoint forwards Better Auth Set-Cookie headers and redirects to the requested in-app path.
Both /api/test/agent-auth and /api/test/e2e-auth are sign-in-only helpers. If the configured principal has not been provisioned yet, use pnpm run e2e:provision or one of the repo auth helper scripts, which now perform provisioning through CLI tooling before they hit the auth route.
Use POST /api/test/e2e-auth only when your tool needs cookie JSON for manual injection, such as Playwright storage state bootstrapping.
If the agent can run repo scripts, the easiest path is:
pnpm run agent:auth -- --session-name codex-demo --principal user --redirect-to /appThat command loads .env.local, auto-provisions the configured principal through CLI tooling when needed, authenticates the named agent-browser session through /api/test/agent-auth, and opens the requested page in the same browser session.
For the common "authenticate, wait, and inspect" flow:
pnpm run agent:inspect -- --session-name codex-demo --principal user --redirect-to /appYou can override the target origin when needed:
pnpm run agent:inspect -- --session-name codex-demo --base-url http://127.0.0.1:3100 --principal user --redirect-to /appAdmin flow:
pnpm run agent:auth -- --session-name codex-admin --principal admin --redirect-to /app/adminFor repo-local Playwright automation, use:
pnpm run playwright:inspect -- --principal user --path /appThat command auto-provisions the configured principal through CLI tooling when needed, authenticates through /api/test/e2e-auth, opens the page with Playwright, and prints a compact JSON summary of the resulting UI. Add --screenshot output/playwright/app.png to save a screenshot artifact.
For reliable browser automation in local development:
- Use
http://127.0.0.1:3000instead ofhttp://localhost:3000. - Always use a named
agent-browsersession so auth state is isolated per run. - After opening a new page, wait for
networkidlebefore the first snapshot. - Re-snapshot after every navigation or DOM-changing interaction.
- Close the named session when done so stale browser state does not leak into later runs.
To close a named session explicitly:
pnpm run agent:close -- --session-name codex-demoSee Agent Browser Workflows for copy-paste patterns covering authenticated snapshots, admin checks, screenshots, and cleanup.
After deploying, link your local project to Netlify for easier management:
# Link your local project to the deployed Netlify site
npx netlify link
# This allows you to:# - Deploy updates with `npx netlify deploy --prod`# - View build logs locally# - Manage environment variables from CLIIn order to send password reset and transactional emails, you need to set up Resend. In order to monitor errors and performance, you need to set up Sentry. For chat functionality, you need to set up OpenRouter. These are optional, but recommended for production.
Add
OPENROUTER_API_KEYto your local.env.localand production environment.Manage the allowed chat models from the admin dashboard instead of syncing a provider catalog.
Resend Setup Guide - Password reset and transactional email configuration
Sentry Setup - Error monitoring and performance tracking
CodeRabbit CLI Setup - AI-powered code review assistance
The template now includes an AWS-backed storage path for file-backed features, with convex remaining the zero-config default and S3 available for malware-scanned storage deployments:
- AWS S3 Storage Setup - CDK infrastructure and runtime environment contract for
s3-primaryands3-mirror - Disaster Recovery Overview - weekly Convex-to-S3 backups, self-hosted Convex failover, and file-storage DR limits
- Disaster Recovery Runbook - operator workflow for backup infra, DR infra, and failover execution
- Disaster Recovery Configuration - GitHub secrets, Secrets Manager inputs, and DR env vars
For guided DR setup across AWS, GitHub, Convex, and Netlify, run:
pnpm run dr:setup
pnpm run dr:netlify:setupFor guided local setup, run:
pnpm run storage:setupThat flow now:
- writes the local runtime storage env vars into
.env.local - syncs the required runtime storage vars into Convex when requested
- derives the storage CDK deploy-time env from those runtime vars
- can preview and deploy the dev storage stack directly
The dev storage commands derive these deploy-time values at runtime:
AWS_CONVEX_STORAGE_CALLBACK_BASE_URLAWS_CONVEX_STORAGE_CALLBACK_SHARED_SECRETAWS_GUARDDUTY_WEBHOOK_SHARED_SECRETAWS_STORAGE_INSPECTION_WEBHOOK_SHARED_SECRETAWS_STORAGE_BROKER_SHARED_SECRETAWS_STORAGE_WORKER_SHARED_SECRETAWS_FILE_SERVE_SIGNING_SECRET- bucket names for quarantine, clean, rejected, and mirror storage
For guided production runtime env setup across Convex prod and Netlify, run:
pnpm run storage:setup:prodThat flow now follows the same storage setup model as local/dev, but writes runtime env to the production storage targets instead:
- sets runtime storage env in Convex prod
- writes the storage operator/deploy env contract to
.env.prod - auto-discovers
StorageBrokerRuntimeUrlandStorageWorkerRuntimeUrlfrom the deployed stack when available - derives the production storage CDK deploy-time env from the collected runtime values
- can preview and deploy the prod storage stack directly
The stage-specific storage infrastructure commands are:
pnpm run storage:preview:dev
pnpm run storage:deploy:dev
pnpm run storage:preview:prod
pnpm run storage:deploy:prod
pnpm run storage:destroy:dev
pnpm run storage:destroy:prodFor DR infrastructure previews and deploys, use:
pnpm run dr:backup:preview
pnpm run dr:backup:deploy
pnpm run dr:backup:destroy
pnpm run dr:ecs:preview
pnpm run dr:ecs:deploy
pnpm run dr:ecs:destroy
pnpm run dr:destroyThe destroy commands are intended to get you back to a clean rerunnable state:
storage:destroy:*deletes the storage stack and also removes the retained S3 bucket and Lambda log groupdr:backup:destroydeletes the backup stack after clearing the backup bucket and backup IAM access keysdr:ecs:destroydeletes the DR ECS stack and then deletes any manual Aurora snapshots left behind by the snapshot removal policydr:destroyperforms the full DR cleanup, including the DR Netlify site, DR-specific GitHub Actions secrets, DR-specific Secrets Manager secrets, and.dr.env.local
MIT License - See LICENSE file for details.