Skip to content
Cloudflare Docs

What is TanStack Start?

TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using Vite and modern web standards.

Create a new TanStack Start

TanStack Start Beta has significantly improved Cloudflare compatibility compared to the Alpha version, making deployment and development much more straightforward.

  1. Create a new TanStack Start project

    Terminal window
    npx gitpick TanStack/router/tree/main/examples/react/start-basic start-basic
    cd start-basic
    npm install

    How is this project set up?

    This command will clone the TanStack Start basic project to your local machine, change directory to the project, and install the dependencies. TanStack provides other examples that you can use by replacing start-basic with the example you want to use.

  2. Develop locally

    After creating your project, run the following command in your project directory to start a local development server. By default this starts a local development server on http://localhost:3000/

    Terminal window
    npm run dev

Preparing for Deployment to Cloudflare Workers

Whether you created a new TanStack Start project or are using an existing project, you'll need to make some changes to prepare for deployment to Cloudflare Workers.

  1. Configure Vite for Cloudflare compatibility

    Update your vite.config.ts file to use the cloudflare-module target for a compatible build:

    vite.config.ts
    import { tanstackStart } from "@tanstack/react-start/plugin/vite";
    import { defineConfig } from "vite";
    import tsConfigPaths from "vite-tsconfig-paths";
    export default defineConfig({
    server: {
    port: 3000,
    },
    plugins: [
    tsConfigPaths({
    projects: ["./tsconfig.json"],
    }),
    tanstackStart({
    target: "cloudflare-module", // Key configuration for Cloudflare compatibility
    }),
    ],
    });

    This single configuration change is all that's needed to make your TanStack Start application compatible with Cloudflare Workers.

  2. Add a Wrangler file

    Create a wrangler.jsonc or wrangler.toml file in the root of your project, wrangler.jsonc is the recommended approach. This file is used to configure the Cloudflare Workers deployment.

    {
    "$schema": "node_modules/wrangler/config-schema.json",
    "name": "my-start-app",
    "main": ".output/server/index.mjs",
    "compatibility_date": "2025-06-25",
    "compatibility_flags": ["nodejs_compat"],
    "assets": {
    "directory": ".output/public"
    },
    "observability": {
    "enabled": true
    },
    "kv_namespaces": [
    {
    "binding": "CACHE",
    "id": "<Your KV ID>"
    }
    ]
    }

    Note that the directory key is set to .output/public, which is the folder that will be filled with the build output. Additionally, the main key is set to .output/server/index.mjs, indicating to Cloudflare Workers where to locate the entry point for your application. The kv_namespaces section shows an example of how to configure a KV namespace binding.

  3. Add deployment scripts to package.json

    Add the following scripts to your package.json file to streamline deployment and type generation:

    "package.json
    {
    "scripts": {
    ...
    "deploy": "npm run build && wrangler deploy",
    "cf-typegen": "wrangler types --env-interface Env"
    }
    }

    The deploy script combines building and deploying in one command, while cf-typegen generates TypeScript types for your Cloudflare bindings.

  4. Build the application

    You must build your application before deploying it to Cloudflare Workers.

    Terminal window
    npm run build
  5. Deploy the application

    You can now use the deploy script to build and deploy your application in one command:

    Terminal window
    npm run deploy

    Alternatively, you can still deploy directly with Wrangler:

    Terminal window
    npx wrangler deploy

Using Cloudflare Bindings

  1. Generate TypeScript types for your bindings

    Before using Cloudflare bindings in your code, generate the TypeScript types to ensure proper type safety:

    Terminal window
    npm run cf-typegen

    This command reads your wrangler.jsonc configuration and generates an Env interface with all your configured bindings.

  2. Create a helper function to get access to Cloudflare bindings

    Create a helper function named bindings.ts in the src/utils folder (create the folder if it doesn't exist), and paste in the below code. The example assumes you have a KV namespace with a binding name of CACHE already created in your account and added to the wrangler file.

    src/utils/bindings.ts
    let cachedEnv: Env | null = null;
    // This gets called once at startup when running locally
    const initDevEnv = async () => {
    const { getPlatformProxy } = await import("wrangler");
    const proxy = await getPlatformProxy();
    cachedEnv = proxy.env as unknown as Env;
    };
    if (import.meta.env.DEV) {
    await initDevEnv();
    }
    /**
    * Will only work when being accessed on the server. Obviously, CF bindings are not available in the browser.
    * @returns
    */
    export function getBindings(): Env {
    if (import.meta.env.DEV) {
    if (!cachedEnv) {
    throw new Error(
    "Dev bindings not initialized yet. Call initDevEnv() first."
    );
    }
    return cachedEnv;
    }
    return process.env as unknown as Env;
    }

    How is this code working?

    The helper function uses getPlatformProxy method from wrangler to provide access to your Cloudflare bindings during local development. The bindings are cached at startup for better performance. In production, bindings are accessed via process.env. Make sure you've run npm run cf-typegen to generate the Env types that this code references.

  3. Example using a Cloudflare Binding in Server Functions

    Now that you have a helper function to get access to your Cloudflare bindings, you can use them in your server functions.

    Remember bindings are only available on the server.

    import { createServerFn } from "@tanstack/react-start";
    import { getBindings } from "~/utils/bindings";
    const personServerFn = createServerFn({ method: "GET" })
    .validator((d: string) => d)
    .handler(async ({ data: name }) => {
    const env = getBindings();
    let growingAge = Number((await env.CACHE.get("age")) || 0);
    growingAge++;
    await env.CACHE.put("age", growingAge.toString());
    return { name, randomNumber: growingAge };
    });

    A special thanks to GitHub user backpine for the code that supports Cloudflare Bindings in TanStack Start, which is demonstrated in their TanStack Start Beta on Cloudflare example.

Environment Handling

The TanStack Start Beta version provides seamless environment handling:

  • Development: Bindings are accessed via getPlatformProxy() from Wrangler and cached at startup
  • Production: Bindings are accessed via process.env

This approach ensures your bindings are properly typed throughout your project and provides a smooth development experience.

By following the steps above, you will have deployed your TanStack Start application to Cloudflare Workers.