Skip to content
/ project-zap Public template

The modern full-stack starter that actually works. TanStack Start + Convex + WorkOS + shadcn/ui

License

Notifications You must be signed in to change notification settings

Stoffberg/project-zap

Project Zap

Project Zap

Production-ready starter for modern web apps
TanStack Start • Convex • WorkOS • shadcn/ui

CI Vercel License

Quick StartEnvironment VariablesDeploymentWhat's Included


Quick Start

# Clone and install
git clone https://github.com/Stoffberg/project-zap.git my-app
cd my-app
bun install

# Set up Convex (creates .env.local)
bunx convex dev

# Add WorkOS Client ID to .env.local
echo "VITE_WORKOS_CLIENT_ID=client_01XXXXXX" >> .env.local

# Run
bun dev

Open localhost:3000

Prerequisites - Installing Required Tools

Bun (Package Manager)

# macOS/Linux
curl -fsSL https://bun.sh/install | bash

# Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"

# Verify installation
bun --version

Accounts Required

Service Sign Up Free Tier
Convex convex.dev Yes - generous limits
WorkOS workos.com/sign-up Yes - 1M MAUs

Environment Variables

Local Development (.env.local)

These are created/required for local development:

Variable Description How to Get
CONVEX_DEPLOYMENT Your Convex deployment ID Auto-generated by bunx convex dev
VITE_CONVEX_URL Convex backend URL Auto-generated by bunx convex dev
VITE_WORKOS_CLIENT_ID WorkOS Client ID WorkOS Dashboard → API Keys
Example .env.local file
# Auto-generated by Convex
CONVEX_DEPLOYMENT=dev:your-deployment-name
VITE_CONVEX_URL=https://your-deployment.convex.cloud

# Add manually from WorkOS Dashboard
VITE_WORKOS_CLIENT_ID=client_01XXXXXXXXXXXXXXXXXXXXXX

Convex Dashboard Environment Variables

These must be set in the Convex Dashboard under Settings → Environment Variables:

Variable Description Required
WORKOS_CLIENT_ID Same as VITE_WORKOS_CLIENT_ID Yes - Auth won't work without this
Why is WORKOS_CLIENT_ID needed in Convex?

Convex needs the WorkOS Client ID to validate JWT tokens. The flow works like this:

  1. User logs in via WorkOS → receives JWT token
  2. Frontend sends JWT to Convex with every request
  3. Convex validates the JWT using your Client ID (from auth.config.ts)
  4. If valid, user is authenticated in Convex queries/mutations

Without WORKOS_CLIENT_ID in Convex, step 3 fails and all auth checks return false.

Production Environment Variables (Vercel)

Variable Description How to Get
CONVEX_DEPLOY_KEY Allows Vercel to deploy to Convex Convex Dashboard → Settings → Deploy Keys
VITE_WORKOS_CLIENT_ID WorkOS Client ID WorkOS Dashboard → API Keys

Convex Setup

Step-by-Step Convex Configuration

1. Initialize Convex

bunx convex dev

This will:

  • Prompt you to log in (or create an account)
  • Create a new Convex project
  • Generate .env.local with your deployment URLs
  • Start the Convex dev server

2. Verify Schema Deployment

After running convex dev, verify your schema deployed:

# Should show your tables
bunx convex data

3. Set Environment Variable in Dashboard

  1. Go to dashboard.convex.dev
  2. Select your project
  3. Go to SettingsEnvironment Variables
  4. Add WORKOS_CLIENT_ID with your WorkOS Client ID value

4. Convex File Structure

convex/
├── schema.ts           # Database schema with tables and indexes
├── auth.config.ts      # WorkOS JWT validation configuration
├── lib/
│   ├── validators.ts   # Shared type validators
│   ├── auth.ts         # Auth helper functions
│   ├── validation.ts   # Input validation
│   ├── constants.ts    # Backend constants
│   └── errors.ts       # Error types
├── todos.ts            # Todo queries and mutations
├── users.ts            # User management
├── preferences.ts      # User preferences
└── http.ts             # HTTP endpoints (webhooks, etc.)

5. Common Convex Commands

# Start dev server (watches for changes)
bunx convex dev

# Deploy to production
bunx convex deploy

# View data in your tables
bunx convex data

# Run a function manually
bunx convex run todos:list

# View logs
bunx convex logs

WorkOS Setup

Step-by-Step WorkOS Configuration

1. Create Account & Organization

  1. Go to workos.com/sign-up
  2. Create your account
  3. You'll be in the Staging environment by default (good for development)

2. Set up AuthKit

  1. In the sidebar, go to AuthenticationAuthKit
  2. Click Set up AuthKit (or Configure if already set up)
  3. Select Use AuthKit's customizable hosted UI
  4. Complete the setup wizard

3. Configure Redirect URIs

  1. Still in AuthKit settings
  2. Under Redirect URIs, add:
    • http://localhost:3000/callback (development)
    • https://your-domain.com/callback (production - add later)

4. Configure CORS

  1. Go to AuthenticationSessions
  2. Find Cross-Origin Resource Sharing (CORS)
  3. Click Manage
  4. Add your origins:
    • http://localhost:3000 (development)
    • https://your-domain.com (production - add later)

5. Get Your Client ID

  1. Go to API Keys in the sidebar
  2. Copy your Client ID (format: client_01XXXXXX)
  3. Add it to your .env.local:
    VITE_WORKOS_CLIENT_ID=client_01XXXXXXXXXXXXXXXXXXXXXX

6. Configure Authentication Methods (Optional)

In AuthKit settings, you can enable:

  • Email + Password - Basic email authentication
  • Magic Link - Passwordless email login
  • Google OAuth - Sign in with Google
  • GitHub OAuth - Sign in with GitHub
  • Microsoft OAuth - Sign in with Microsoft
  • Apple OAuth - Sign in with Apple

Each social provider requires:

  1. Creating an OAuth app in that provider's dashboard
  2. Adding the Client ID and Secret to WorkOS

7. Customize Branding (Optional)

In AuthKitBranding:

  • Upload your logo
  • Set primary color
  • Customize button styles
  • Add custom CSS

Deployment

Deploy to Vercel

Step-by-Step Vercel Deployment

1. Prepare Your Repository

# Make sure everything is committed
git add -A
git commit -m "Ready for deployment"
git push origin main

2. Get Your Deploy Key from Convex

  1. Go to dashboard.convex.dev
  2. Select your project
  3. Go to SettingsDeploy Keys
  4. Click Generate Deploy Key
  5. Copy the key (you won't see it again)

3. Create Vercel Project

  1. Go to vercel.com/new
  2. Import your GitHub repository
  3. Configure the project:
Setting Value
Framework Preset Other
Build Command bunx convex deploy --cmd 'bun run build'
Output Directory .output
Install Command bun install

4. Add Environment Variables

In Vercel project settings → Environment Variables, add:

Name Value
CONVEX_DEPLOY_KEY Your deploy key from step 2
VITE_WORKOS_CLIENT_ID Your WorkOS Client ID

5. Deploy

Click Deploy and wait for the build to complete.

6. Configure WorkOS for Production

After deployment, update WorkOS settings:

  1. Add Redirect URI: https://your-vercel-domain.vercel.app/callback
  2. Add CORS Origin: https://your-vercel-domain.vercel.app

7. Set Production Convex Environment Variable

  1. Go to dashboard.convex.dev
  2. Switch to your Production deployment
  3. Go to SettingsEnvironment Variables
  4. Add WORKOS_CLIENT_ID with your Client ID
Custom Domain Setup

1. Add Domain in Vercel

  1. Go to your Vercel project → SettingsDomains
  2. Add your custom domain
  3. Follow DNS configuration instructions

2. Update WorkOS Settings

Add to your WorkOS configuration:

  • Redirect URI: https://yourdomain.com/callback
  • CORS Origin: https://yourdomain.com

3. Update Vercel Environment (if needed)

If you have environment-specific configs, update them for your custom domain.


What's Included

Category Tech
Framework TanStack Start (React 19, SSR, file-based routing)
Database Convex (real-time, serverless, type-safe)
Auth WorkOS AuthKit (SSO, MFA, social login)
UI shadcn/ui + Tailwind v4
Tooling TypeScript, Biome, Vite
Features

UI Components (30+)

  • Buttons, inputs, forms, selects, checkboxes
  • Cards, dialogs, sheets, popovers
  • Tables with sorting, filtering, pagination
  • Navigation menus, tabs, breadcrumbs
  • Toast notifications, alerts, badges
  • Dark mode with system preference detection

Authentication

  • Complete sign in/sign up flow
  • Social login (Google, GitHub, etc.)
  • Session management
  • Protected routes with auth guards
  • User profile management

Data Features

  • Real-time updates (Convex subscriptions)
  • File uploads with Convex storage
  • Server-side pagination and search
  • Optimistic updates for mutations

Mobile & PWA

  • Progressive Web App - installable, works offline
  • True device detection (not just screen size)
  • Bottom navigation on mobile
  • Sheet-based forms and inputs
  • Card layouts for tables on mobile
  • Touch-optimized (44px targets)
  • Safe area support for notched devices

Developer Experience

  • Type-safe from database to UI
  • File-based routing
  • Hot module replacement
  • ESLint + Biome for linting/formatting
  • Pre-commit hooks with lint-staged

Project Structure

src/
├── routes/                    # File-based routing
│   ├── index.tsx              # Landing page (public)
│   ├── _app.tsx               # Auth guard layout
│   └── _app/                  # Protected pages
│       ├── dashboard.tsx
│       ├── todos.tsx
│       └── settings/
├── components/
│   ├── ui/                    # shadcn/ui primitives
│   ├── features/              # Feature-specific components
│   └── layouts/               # Page layouts
├── hooks/                     # Custom React hooks
├── lib/                       # Utilities
└── integrations/              # Third-party integrations
    ├── convex/                # Convex provider setup
    └── workos/                # WorkOS provider setup

convex/
├── schema.ts                  # Database schema
├── auth.config.ts             # JWT validation config
├── lib/                       # Shared utilities
└── *.ts                       # Domain modules (todos, users, etc.)
Routing Conventions
File Route Description
index.tsx / Landing page
about.tsx /about Static page
_app.tsx Layout Auth guard for nested routes
_app/dashboard.tsx /dashboard Protected page
_app/users/$userId.tsx /users/:userId Dynamic route
_app/settings/index.tsx /settings Nested index
__root.tsx Root layout Wraps entire app

Prefixes:

  • _ = Layout (doesn't add to URL)
  • $ = Dynamic segment
  • __ = Special (root only)

Scripts

Command Description
bun dev Start dev server
bun build Production build
bun run lint Lint with Biome
bun run check Lint + format (auto-fix)
bun run typecheck TypeScript check
bunx convex dev Start Convex dev server
bunx convex deploy Deploy Convex to production

Adding UI Components

bunx shadcn@latest add button
bunx shadcn@latest add card dialog sheet
bunx shadcn@latest add form input label

Browse all components at ui.shadcn.com


Troubleshooting

Authentication Issues

"Auth not working after login"

  1. Check Convex environment variable:

    • Go to Convex Dashboard → Settings → Environment Variables
    • Verify WORKOS_CLIENT_ID is set and matches your WorkOS Client ID
  2. Sync auth config:

    bunx convex dev
  3. Check CORS in WorkOS:

    • Go to WorkOS Dashboard → Authentication → Sessions → CORS
    • Verify your domain is listed
  4. Check Redirect URI:

    • Go to WorkOS Dashboard → Authentication → AuthKit
    • Verify http://localhost:3000/callback is in Redirect URIs

"Invalid redirect_uri"

Your redirect URI doesn't match what's configured in WorkOS. Add the exact URI shown in the error to your WorkOS AuthKit settings.

"CORS error"

Add your domain to WorkOS CORS settings:

  1. WorkOS Dashboard → Authentication → Sessions
  2. Find CORS section → Manage
  3. Add your origin (e.g., http://localhost:3000)
Convex Issues

"Missing VITE_CONVEX_URL"

Run Convex to generate the environment file:

bunx convex dev

"Convex deployment not found"

  1. Check .env.local has correct CONVEX_DEPLOYMENT
  2. Verify you're logged into the correct Convex account:
    bunx convex logout
    bunx convex dev

"Schema mismatch"

Your local schema differs from deployed. Push your schema:

bunx convex dev

"Function not found"

Convex functions might not be synced. Restart the dev server:

# Kill existing process, then:
bunx convex dev
Build & Deployment Issues

"Build fails on Vercel"

  1. Check environment variables are set in Vercel project settings
  2. Verify build command: bunx convex deploy --cmd 'bun run build'
  3. Check logs for specific error messages

"CONVEX_DEPLOY_KEY invalid"

Generate a new deploy key:

  1. Convex Dashboard → Settings → Deploy Keys
  2. Generate new key
  3. Update in Vercel environment variables

"Type errors in production build"

Run typecheck locally first:

bun run typecheck
Development Issues

"Port 3000 already in use"

Kill the process using the port:

# macOS/Linux
lsof -ti:3000 | xargs kill -9

# Or use a different port
PORT=3001 bun dev

"Module not found"

Clear node_modules and reinstall:

rm -rf node_modules bun.lockb
bun install

"Convex types out of sync"

Regenerate Convex types:

bunx convex dev

This generates fresh types in convex/_generated/.


Authentication Flow

┌─────────┐     ┌─────────┐     ┌─────────┐     ┌─────────┐
│  User   │────▶│ WorkOS  │────▶│Frontend │────▶│ Convex  │
│ clicks  │     │ hosted  │     │/callback│     │ backend │
│ sign in │     │   UI    │     │         │     │         │
└─────────┘     └─────────┘     └─────────┘     └─────────┘
                    │                │               │
                    │ 1. Login       │               │
                    │◀───────────────│               │
                    │                │               │
                    │ 2. JWT token   │               │
                    │───────────────▶│               │
                    │                │               │
                    │                │ 3. JWT in     │
                    │                │    requests   │
                    │                │──────────────▶│
                    │                │               │
                    │                │ 4. Validate   │
                    │                │    JWT        │
                    │                │◀──────────────│

Important: Always use useConvexAuth() from convex/react to check auth state, not WorkOS's useAuth(). This ensures the Convex backend has validated the token.


License

MIT


GitHubIssuesReleases

About

The modern full-stack starter that actually works. TanStack Start + Convex + WorkOS + shadcn/ui

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published

Contributors 2

  •  
  •