A template for SSR-ready React applications powered by TanStack Start and Cloudflare Workers.
- Framework: TanStack Start (React 19)
- Routing: TanStack Router (file-based)
- Styling: Tailwind CSS
- Hosting: Cloudflare Workers
- Toolchain: Vite+ (
vp— Vite, Vitest, Oxlint, Oxfmt) - Git Hooks: Vite+ hooks (
vp staged/.vite-hooks) - Package Manager: pnpm (via
vp install)
TanStack Intent is the CLI that loads the agent skills that ship with the installed TanStack packages. Day-to-day commands in this template stay vp.
- Node.js: CI uses 24.19.0 via
setup-vp. Vite+ requires Node.js 22.18+, 24.11+, or 26+. Git hooks (vp staged) require Node.js 22.22.1+, 24.11+, or 26+. - pnpm: provided by Vite+; see
packageManagerinpackage.json. - Vite+ CLI (
vp):
curl -fsSL https://vite.plus | bashThen open a new shell (or ensure ~/.vite-plus/bin is on your PATH) and run vp help.
A Cloudflare account is required only when you deploy.
After you create a repository from this template (or clone it):
cd tanstack-cloudflare-template
vp install # Install dependencies
vp run prepare # Install Git hook dispatcher (also runs via prepare)
vp dev # Start the Vite+ dev serverThe app is served at http://localhost:5173/ (Vite's default). This template does not set server.port, so the port is 5173, not 3000.
package.json scripts still work through pnpm (pnpm dev, pnpm check, …) or vp run <script>. Prefer the vp built-ins above for day-to-day work.
vp install # Install dependencies
vp run prepare # Install Git hook dispatcher (also runs via prepare)
vp dev # Start dev server (http://localhost:5173/)
vp build # Production build (client + SSR / workerd)
vp preview # Preview production build
vp run deploy # Build and deploy to Cloudflare Workers
vp test # Run tests
vp check # Format + lint + type-check
vp check --fix # Autofix format/lint (also type-checks)
vp run cf-typegen # Generate Cloudflare bindings typesTest files should import from vite-plus/test, not vitest. Vitest is provided by vite-plus and is not a direct dependency, so from "vitest" will not resolve under pnpm.
Put non-secret values in vars in wrangler.jsonc. Do not commit secrets: use Wrangler secrets in production and .dev.vars locally (gitignored; see .gitignore).
After you change wrangler.jsonc (bindings, vars, compatibility flags, or similar), regenerate types:
vp run cf-typegenThis updates worker-configuration.d.ts. Commit that file so CI can verify it with vp run cf-typegen --check.
Access bindings and vars from server-side code:
import { env } from "cloudflare:workers";
export function getGreeting() {
return env.MY_VAR;
}See Cloudflare bindings and environment variables.
A Cloudflare account is required. Authenticate with Wrangler as described in TanStack Start hosting (Cloudflare) and Wrangler login.
Then deploy:
vp run deployThis runs the production build and deploys to Cloudflare Workers. See also Cloudflare: TanStack Start.
src/
routes/ # File-based routing
router.tsx # Router configuration
styles.css # Global styles
.vite-hooks/ # Project-owned Git hooks (pre-commit)
wrangler.jsonc # Cloudflare Workers config
vite.config.ts # Vite+ config (dev/build/lint/fmt/staged/test)