Kurzfassung: Das Deployen einer TanStack Start-Anwendung auf Cloudflare Workers erfordert eine sorgfältige Konfiguration von
wrangler.jsonc, ein durchdachtes Management von Umgebungsvariablen zwischen Dev- und Produktionsumgebungen, die Einrichtung einer D1-Datenbank mit automatisierten Migrations, die Integration von R2 Object Storage sowie eine solide CI/CD-Pipeline. Dieser Guide begleitet Sie durch jeden Schritt des Prozesses – vom initialen Scaffolding bis zum Production-Monitoring –, damit Sie mit voller Zuversicht auf Cloudflares Edge-Netzwerk deployen können.
Einleitung: Warum Cloudflare Workers für TanStack Start
TanStack Start ist ein Full-Stack-React-Framework, das auf Vinxi aufbaut und Serverseitiges Rendern, Streaming sowie Static Generation in das TanStack-Ökosystem bringt. Was das Deployment betrifft, bieten Cloudflare Workers eine einzigartig überzeugende Laufzeitumgebung für Start-Anwendungen.
Anders als traditionelle Node.js-Server, die Cold Starts, Regions-Pinning und manuelles Skalieren erfordern, laufen Cloudflare Workers auf V8-Isolates über 330+ Standorte weltweit. Das bedeutet: Ihre TanStack Start-App kann initiales HTML ausliefern, Content-Updates streamen und API-Anfragen bearbeiten – alles vom Edge aus, nah an jedem Nutzer.
Doch mit diesem architektonischen Wandel gehen auch neue Konfigurationsherausforderungen einher. Die Workers-Laufzeitumgebung unterstützt keine Node.js-APIs wie fs, net oder child_process. Ihre Build-Pipeline, Umgebungsvariablen und Datenbankverbindungen müssen alle angepasst werden. Dieser Guide deckt das produktionsreife Setup ab, mit dem wir TanStack Start auf Cloudflare Workers im großen Maßstab betreiben.
wrangler.jsonc: Tiefgehende Konfiguration
Die wrangler.jsonc-Datei ist die zentrale Anlaufstelle für Ihre Cloudflare-Deployment-Konfiguration. Hier ist die Produktionskonfiguration, die wir verwenden – mit Erklärungen versehen:
{
"$schema": "https://raw.githubusercontent.com/cloudflare/workers-sdk/main/packages/wrangler/config-schema.json",
"name": "tanstack-ship",
"main": "./dist/worker.js",
"compatibility_date": "2026-05-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": "./dist/public",
"binding": "ASSETS",
"html_handling": "auto",
"not_found_handling": "404"
},
"workers_dev": false,
"route": {
"pattern": "tanstack-ship.com",
"custom_domain": true,
"zone_id": "YOUR_ZONE_ID"
},
"d1_databases": [
{
"binding": "DB",
"database_name": "tanstack-ship-db",
"database_id": "YOUR_D1_DATABASE_ID",
"migrations_dir": "./migrations"
}
],
"r2_buckets": [
{
"binding": "R2",
"bucket_name": "tanstack-ship-assets"
}
],
"vars": {
"APP_VERSION": "1.0.0",
"SENTRY_DSN": ""
},
"env": {
"production": {
"vars": {
"SENTRY_DSN": "https://your-sentry-dsn@o123.ingest.sentry.io/456"
},
"routes": [
{
"pattern": "tanstack-ship.com",
"custom_domain": true
}
]
},
"preview": {
"workers_dev": true,
"vars": {
"SENTRY_DSN": ""
}
}
},
"observability": {
"enabled": true,
"head_sampling_rate": 0.1
}
}
Erklärung der wichtigsten Felder
compatibility_flags: Das Flagnodejs_compataktiviert eine Teilmenge der Node.js-APIs (z. B.Buffer,process.env). Viele npm-Pakete sind darauf angewiesen – halten Sie dieses Flag aktiviert.assets:html_handling: "auto"weist Workers an,index.htmlfür Verzeichnisanfragen auszuliefern – essenziell für den Client-seitigen Routing-Fallback.not_found_handling: "404"stellt sicher, dass unbekannte Pfade einen korrekten 404 zurückgeben.env-Blöcke: Definieren Sie umgebungsspezifische Overrides. Diepreview-Umgebung nutztworkers_dev: truefür*.workers.dev-Subdomains, währendproductioneine Custom Domain bindet.
Umgebungsvariablen: Dev vs. Produktion
Lokale Entwicklung
Erstellen Sie eine .dev.vars-Datei im Projekt-Root:
# .dev.vars – wird von wrangler dev geladen
SENTRY_DSN=
STRIPE_SECRET_KEY=your-stripe-secret-key
RESEND_API_KEY=your-resend-api-key
PUBLIC_SITE_URL=http://localhost:5173
Der wrangler dev-Befehl von Cloudflare liest .dev.vars automatisch ein und injiziert die Werte in die Worker-Laufzeit.
Produktions-Secrets
Für Produktions-Secrets nutzen Sie wrangler secret put, um sensible Werte aus Ihren Konfigurationsdateien herauszuhalten:
npx wrangler secret put SENTRY_DSN
npx wrangler secret put STRIPE_SECRET_KEY
Secrets werden verschlüsselt gespeichert und zur Laufzeit auf dem Edge injiziert. Sie sind nicht im vars-Abschnitt von wrangler.jsonc zugänglich – ein häufiger Sicherheitsfehler.
Typsicheres Zugriffsmuster
Zentralisieren Sie den gesamten Zugriff auf Umgebungsvariablen in einem einzigen Modul mit Zod-Validierung für Laufzeitsicherheit:
// src/env.ts
import { z } from "zod";
const envSchema = z.object({
SENTRY_DSN: z.string().optional(),
STRIPE_SECRET_KEY: z.string().min(1),
RESEND_API_KEY: z.string().min(1),
PUBLIC_SITE_URL: z.string().url().default("http://localhost:5173"),
DB: z.any(), // D1-Bindung
R2: z.any(), // R2-Bindung
ASSETS: z.any(), // Assets-Bindung
});
export type Env = z.infer<typeof envSchema>;
export function parseEnv(env: Record<string, unknown>): Env {
const result = envSchema.safeParse(env);
if (!result.success) {
console.error("Ungültige Umgebungsvariablen:", result.error.flatten());
throw new Error("Umgebungsvalidierung fehlgeschlagen");
}
return result.data;
}
Dieses Muster bietet Ihnen Laufzeit-Typsicherheit und erkennt fehlkonfigurierte Umgebungen früh in der CI.
D1-Datenbank: Einrichtung und Migrations
1. Datenbank erstellen
npx wrangler d1 create tanstack-ship-db
Kopieren Sie die zurückgegebene database_id in Ihre wrangler.jsonc.
2. Migrations schreiben
Platzieren Sie SQL-Migrationsdateien in einem migrations/-Verzeichnis:
-- migrations/0001_users.sql
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_users_email ON users(email);
3. Migrations anwenden
Lokal:
npx wrangler d1 migrations apply tanstack-ship-db --local
In Produktion:
npx wrangler d1 migrations apply tanstack-ship-db --remote
4. Automatisierte Migrations in der CI
# .github/workflows/deploy.yml (Auszug)
- name: D1-Migrations anwenden
run: npx wrangler d1 migrations apply tanstack-ship-db --remote
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Führen Sie Migrations vor dem Deployment der neuen Worker-Version durch, um Zero-Downtime-Deployments zu gewährleisten.
R2 Object Storage: Integration
Fügen Sie eine R2-Bindung in wrangler.jsonc hinzu und konfigurieren Sie dann den Client für Datei-Uploads und -Abruf:
// src/lib/r2-client.ts
import type { R2Bucket } from "@cloudflare/workers-types";
let bucket: R2Bucket;
export function initR2(r2: R2Bucket) {
bucket = r2;
}
export async function uploadFile(
key: string,
body: ReadableStream | ArrayBuffer,
contentType: string
) {
return bucket.put(key, body, {
httpMetadata: { contentType },
customMetadata: { uploadedAt: new Date().toISOString() },
});
}
export async function getFile(key: string) {
const object = await bucket.get(key);
if (!object) return null;
return object;
}
Produktions-Optimierungen
Caching-Header
function setCachingHeaders(response: Response, pathname: string): Response {
const headers = new Headers(response.headers);
// Statische Assets: Langzeit-Cache
if (/\.(js|css|png|jpg|webp|svg|woff2?)$/i.test(pathname)) {
headers.set("Cache-Control", "public, max-age=31536000, immutable");
}
// HTML-Seiten: Kurzer CDN-Cache, kein Browser-Cache
else if (pathname.endsWith(".html") || !pathname.includes(".")) {
headers.set("Cache-Control", "public, s-maxage=60, stale-while-revalidate=600");
}
return new Response(response.body, {
status: response.status,
headers,
});
}
Streaming aktivieren
// wrangler.jsonc
{
"compatibility_flags": ["nodejs_compat"],
"streaming": true
}
Streaming ermöglicht es Suspense-Boundaries, Content progressiv auszuliefern – das verbessert die wahrgenommene Performance spürbar.
CI/CD-Pipeline: Einrichtung
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- run: npm ci
- run: npm run typecheck
- run: npm run lint
- run: npm run build
env:
PUBLIC_SITE_URL: ${{ vars.PUBLIC_SITE_URL }}
- name: D1-Migrations anwenden
run: npx wrangler d1 migrations apply tanstack-ship-db --remote
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- name: Auf Cloudflare Workers deployen
run: npx wrangler deploy --env production
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Häufige Deployment-Probleme und Lösungen
-
„Module not found" für Node.js Built-ins: Aktivieren Sie das
nodejs_compat-Flag. Falls das Modul weiterhin fehlschlägt, finden Sie eine Workers-kompatible Alternative. -
D1-Migration schlägt fehl mit „Table already exists": Verwenden Sie stets
CREATE TABLE IF NOT EXISTSundCREATE INDEX IF NOT EXISTS. -
Client-seitiges Routing gibt 404 bei Refresh zurück: Stellen Sie sicher, dass
html_handling: "auto"inwrangler.jsoncgesetzt ist. -
Umgebungsvariablen sind zur Laufzeit undefined: Verschieben Sie Secrets zu
wrangler secret putund nutzen Sievarsnur für nicht-sensible Konfiguration. -
Bundle überschreitet das 1-MB-Limit: Stellen Sie sicher, dass Ihr Vite-Build Ungenutztes entfernt. Nutzen Sie dynamisches
import()für schwere Abhängigkeiten.
Fazit
Das Deployen von TanStack Start auf Cloudflare Workers ist eine der performantesten und kosteneffektivsten Arten, eine Full-Stack-React-Anwendung auszuliefern. Die Edge-Laufzeit bietet Ihnen globale Verteilung, instantane Cold Starts und ein großzügiges Free-Tier.
Die wichtigsten Erkenntnisse:
- Validieren Sie Ihre Umgebungsvariablen mit Zod am Edge, bevor irgendeine Logik ausgeführt wird.
- Führen Sie Migrations vor Deployments durch, nicht danach.
- Setzen Sie Caching-Header aggressiv, aber durchdacht – HTML bekommt
s-maxage, Assets bekommenimmutable. - Aktivieren Sie Observability frühzeitig – Sie werden diese Traces brauchen, wenn etwas schiefgeht.
Für eine praxisnahe Anleitung zum Erstellen einer vollständigen Anwendung lesen Sie das TanStack Start End-to-End Tutorial. Um Ihre D1-Datenbank in Produktion zu bringen, lesen Sie Edge Database: Cloudflare D1 in Production. Für offizielle Referenzen konsultieren Sie die Wrangler CLI-, Cloudflare D1- und R2-Dokumentation.