Claude-skills vite-flare-starter
Scaffold a full-stack Cloudflare app from vite-flare-starter — React 19, Hono, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui, TanStack Query, R2, Workers AI. Run setup.sh to clone, configure, and deploy.
git clone https://github.com/jezweb/claude-skills
T=$(mktemp -d) && git clone --depth=1 https://github.com/jezweb/claude-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/cloudflare/skills/vite-flare-starter" ~/.claude/skills/jezweb-claude-skills-vite-flare-starter && rm -rf "$T"
plugins/cloudflare/skills/vite-flare-starter/SKILL.mdVite Flare Starter
Clone and configure the batteries-included Cloudflare starter into a standalone project. Produces a fully rebranded, deployable full-stack app.
Stack
| Layer | Technology | Version |
|---|---|---|
| Frontend | React, Vite, Tailwind CSS, shadcn/ui | 19, 6.x, v4, latest |
| Backend | Hono (on Cloudflare Workers) | 4.x |
| Database | D1 (SQLite at edge) + Drizzle ORM | 0.38+ |
| Auth | better-auth (Google OAuth + email/password) | latest |
| Storage | R2 (S3-compatible object storage) | — |
| AI | Workers AI binding | — |
| Data Fetching | TanStack Query | v5 |
Cloudflare Bindings
| Binding | Type | Purpose |
|---|---|---|
| D1 Database | Primary application database |
| R2 Bucket | User avatar storage |
| R2 Bucket | General file uploads |
| Workers AI | AI model inference |
Project Structure
src/ ├── client/ # React frontend │ ├── components/ # UI components │ ├── hooks/ # Custom hooks + TanStack Query │ ├── pages/ # Route pages │ ├── lib/ # Utilities (auth client, etc.) │ └── main.tsx # App entry point ├── server/ # Hono backend │ ├── index.ts # Worker entry point │ ├── routes/ # API routes │ ├── middleware/ # Auth, CORS, etc. │ └── db/ # Drizzle schema + queries └── shared/ # Shared types between client/server
Key Commands
| Command | Purpose |
|---|---|
| Start local dev server |
| Production build |
| Deploy to Cloudflare |
| Apply migrations locally |
| Apply migrations to production |
| Generate migration from schema changes |
Workflow
Step 1: Gather Project Info
Ask for:
| Required | Optional |
|---|---|
| Project name (kebab-case) | Admin email |
| Description (1 sentence) | Google OAuth credentials |
| Cloudflare account | Custom domain |
Step 2: Clone and Configure
2a. Clone and clean
git clone https://github.com/jezweb/vite-flare-starter.git PROJECT_DIR --depth 1 cd PROJECT_DIR rm -rf .git git init
2b. Find-replace targets
Replace
vite-flare-starter with the project name in these locations:
| File | Target | Replace with |
|---|---|---|
| (worker name) | |
| | |
| | |
| | |
| | |
| | |
| content | App display name (Title Case) |
Also in
wrangler.jsonc:
- Remove hardcoded
line (let wrangler prompt or use env var)account_id - Replace
value withdatabase_idREPLACE_WITH_YOUR_DATABASE_ID
Reset
package.json version to "0.1.0".
Use the Edit tool for replacements (preferred over sed to avoid macOS/GNU differences).
2c. Generate auth secret
BETTER_AUTH_SECRET=$(openssl rand -hex 32 2>/dev/null || python3 -c "import secrets; print(secrets.token_hex(32))")
2d. Create .dev.vars
Convert kebab-case project name:
my-cool-app becomes Display My Cool App, ID my_cool_app.
# Local Development Environment Variables # DO NOT COMMIT THIS FILE TO GIT # Authentication (better-auth) BETTER_AUTH_SECRET=<generated> BETTER_AUTH_URL=http://localhost:5173 # Google OAuth (optional) GOOGLE_CLIENT_ID= GOOGLE_CLIENT_SECRET= # Email Auth Control (disabled by default) # ENABLE_EMAIL_LOGIN=true # ENABLE_EMAIL_SIGNUP=true # Application Configuration APP_NAME=<Display Name> VITE_APP_NAME=<Display Name> VITE_APP_ID=<app_id> VITE_TOKEN_PREFIX=<app_id>_ VITE_GITHUB_URL= VITE_FOOTER_TEXT= NODE_ENV=development
2e. Create Cloudflare resources (optional)
npx wrangler d1 create PROJECT_NAME-db # Extract database_id from output, update wrangler.jsonc npx wrangler r2 bucket create PROJECT_NAME-avatars npx wrangler r2 bucket create PROJECT_NAME-files
2f. Install and migrate
pnpm install pnpm run db:migrate:local
2g. Initial commit
git add -A git commit -m "Initial commit from vite-flare-starter"
Step 3: Manual Configuration
- Google OAuth (if using): Go to Google Cloud Console, create OAuth 2.0 Client ID, add redirect URI
, copy Client ID and Secret tohttp://localhost:5173/api/auth/callback/google.dev.vars - Favicon: Replace
public/favicon.svg - CLAUDE.md: Update project description, remove vite-flare-starter references
- index.html: Update
and meta description<title>
Step 4: Verify Locally
pnpm dev
Check: http://localhost:5173 loads, shows YOUR app name, sign-up/sign-in works (if OAuth configured).
Step 5: Deploy to Production
# Set production secrets openssl rand -base64 32 | npx wrangler secret put BETTER_AUTH_SECRET echo "https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put BETTER_AUTH_URL echo "http://localhost:5173,https://PROJECT_NAME.SUBDOMAIN.workers.dev" | npx wrangler secret put TRUSTED_ORIGINS # If using Google OAuth echo "your-client-id" | npx wrangler secret put GOOGLE_CLIENT_ID echo "your-client-secret" | npx wrangler secret put GOOGLE_CLIENT_SECRET # Migrate remote database pnpm run db:migrate:remote # Build and deploy pnpm run build && pnpm run deploy
Critical: After first deploy, update BETTER_AUTH_URL with your actual Worker URL. Add the production URL to Google OAuth redirect URIs.
Security Fingerprints
Change all of these so attackers cannot identify your site uses this starter:
| Location | Default Value | How to Change |
|---|---|---|
| Page title | "Vite Flare Starter" | |
| App name in UI | "Vite Flare Starter" | env var |
| localStorage keys | | env var |
| API tokens | prefix | env var |
| GitHub links | starter repo | (set empty to hide) |
| Worker name | | |
| Database name | | |
| R2 buckets | | |
Environment Variables
Branding (VITE_ prefix = available in frontend)
| Variable | Purpose | Example |
|---|---|---|
| Display name in UI | "My Cool App" |
| localStorage prefix, Sentry | "mycoolapp" |
| API token prefix | "mca_" |
| GitHub link (empty = hidden) | "" |
| Footer copyright text | "2026 My Company" |
| Server-side app name | "My Cool App" |
Auth
| Variable | Purpose | Notes |
|---|---|---|
| Session encryption | |
| Auth base URL | Must match actual URL exactly |
| Allowed origins | Comma-separated, include localhost + prod |
| Google OAuth | From Google Cloud Console |
| Google OAuth | From Google Cloud Console |
| Enable email/password | "true" to enable |
| Enable email signup | Requires ENABLE_EMAIL_LOGIN |
Email (Optional)
| Variable | Purpose | Notes |
|---|---|---|
| Sender address | For verification/password reset |
| Email service API key | Resend recommended |
Common Customisations
Adding a New Database Table
- Add schema in
src/server/db/schema.ts - Generate migration:
pnpm db:generate - Apply locally:
pnpm db:migrate:local - Apply to production:
pnpm db:migrate:remote
Adding a New API Route
- Create route file in
src/server/routes/ - Register in
src/server/index.ts - Add TanStack Query hook in
src/client/hooks/
Changing Auth Providers
Edit
src/server/auth.ts: add provider to socialProviders, add credentials to .dev.vars and production secrets, update client-side login buttons.
Feature Flags
Control features via environment variables:
VITE_FEATURE_STYLE_GUIDE=true, VITE_FEATURE_COMPONENTS=true. Add your own in src/client/lib/features.ts.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Auth redirects to homepage silently | Missing TRUSTED_ORIGINS | Set TRUSTED_ORIGINS with all valid URLs |
| "Not authorized" on deploy | Wrong account_id | Remove account_id from wrangler.jsonc or set yours |
| Database 500 errors | Missing migrations | Run and |
| localStorage shows "vite-flare-starter" | Missing VITE_APP_ID | Set in .dev.vars |
| Auth fails in production only | BETTER_AUTH_URL mismatch | Must match actual Worker URL exactly (https, no trailing slash) |
| "redirect_uri_mismatch" on Google sign-in | OAuth redirect URI missing | Add production URL to Google Cloud Console OAuth redirect URIs |
| Secret changes have no effect | Not redeployed | does NOT redeploy. Run after |
Production Deployment Checklist
-
set (different from dev!)BETTER_AUTH_SECRET -
matches actual Worker URLBETTER_AUTH_URL -
includes all valid URLsTRUSTED_ORIGINS - Google OAuth redirect URI includes production URL
- Remote database migrated (
)pnpm db:migrate:remote - No
references in config filesvite-flare-starter - Favicon replaced
- CLAUDE.md updated
-
is NOT committed (check.dev.vars
).gitignore