# TanStack Start

import { Tabs, TabItem } from '@astrojs/starlight/components';

This guide shows how to initialize and deploy a TanStack Start application to Cloudflare using Alchemy.

## Init

Start by creating a new TanStack Start project with Alchemy:

<Tabs syncKey="pkgManager">
  <TabItem label="bun">
    ```sh
    bunx alchemy create my-tanstack-app --template=tanstack-start
    cd my-tanstack-app
    ```
  </TabItem>
  <TabItem label="npm">
    ```sh
    npx alchemy create my-tanstack-app --template=tanstack-start
    cd my-tanstack-app
    ```
  </TabItem>
  <TabItem label="pnpm">
    ```sh
    pnpm dlx alchemy create my-tanstack-app --template=tanstack-start
    cd my-tanstack-app
    ```
  </TabItem>
  <TabItem label="yarn">
    ```sh
    yarn dlx alchemy create my-tanstack-app --template=tanstack-start
    cd my-tanstack-app
    ```
  </TabItem>
</Tabs>

## Log in to Cloudflare

Authenticate once with your Cloudflare account:

<Tabs syncKey="pkgManager">
  <TabItem label="bun">
    ```sh
    bun wrangler login
    ```
  </TabItem>
  <TabItem label="npm">
    ```sh
    npx wrangler login
    ```
  </TabItem>
  <TabItem label="pnpm">
    ```sh
    pnpm wrangler login
    ```
  </TabItem>
  <TabItem label="yarn">
    ```sh
    yarn wrangler login
    ```
  </TabItem>
</Tabs>

:::tip
Alchemy login creates Cloudflare OAuth tokens for alchemy. See the [Cloudflare](/guides/cloudflare) guide for other options.
:::

## Deploy

Run the deploy script generated by the template:

<Tabs syncKey="pkgManager">
  <TabItem label="bun">
    ```sh
    bun run deploy
    ```
  </TabItem>
  <TabItem label="npm">
    ```sh
    npm run deploy
    ```
  </TabItem>
  <TabItem label="pnpm">
    ```sh
    pnpm run deploy
    ```
  </TabItem>
  <TabItem label="yarn">
    ```sh
    yarn run deploy
    ```
  </TabItem>
</Tabs>

You'll get the live URL of your TanStack Start application:

```sh
{
  url: "https://website.<your-account>.workers.dev",
}
```

## Local Development

Work locally using the dev script:

<Tabs syncKey="pkgManager">
  <TabItem label="bun">
    ```sh
    bun run dev
    ```
  </TabItem>
  <TabItem label="npm">
    ```sh
    npm run dev
    ```
  </TabItem>
  <TabItem label="pnpm">
    ```sh
    pnpm run dev
    ```
  </TabItem>
  <TabItem label="yarn">
    ```sh
    yarn run dev
    ```
  </TabItem>
</Tabs>

## Destroy

Clean up all Cloudflare resources created by this stack:

<Tabs syncKey="pkgManager">
  <TabItem label="bun">
    ```sh
    bun run destroy
    ```
  </TabItem>
  <TabItem label="npm">
    ```sh
    npm run destroy
    ```
  </TabItem>
  <TabItem label="pnpm">
    ```sh
    pnpm run destroy
    ```
  </TabItem>
  <TabItem label="yarn">
    ```sh
    yarn run destroy
    ```
  </TabItem>
</Tabs>

## What files are created

### `.env`

Alchemy requires a locally set password to encrypt Secrets that are stored in state. Be sure to change this.

:::note
See the [Secret](/concepts/secret) documentation to learn more.
:::

```
ALCHEMY_PASSWORD=change-me
```

### `alchemy.run.ts`

```typescript
import alchemy from "alchemy";
import { TanStackStart } from "alchemy/cloudflare";

const app = await alchemy("my-tanstack-app");

export const worker = await TanStackStart("website");

console.log({
  url: worker.url,
});

await app.finalize();
```

### `types/env.d.ts`

```typescript
// Auto-generated Cloudflare binding types.
// @see https://alchemy.run/concepts/bindings/#type-safe-bindings

import type { worker } from "../alchemy.run.ts";

export type CloudflareEnv = typeof worker.Env;

declare global {
  type Env = CloudflareEnv;
}

declare module "cloudflare:workers" {
  namespace Cloudflare {
    export interface Env extends CloudflareEnv {}
  }
}
```

### `tsconfig.json`

The CLI updated the `tsconfig.json` to include `alchemy.run.ts` and register `@cloudflare/workers-types` + `types/env.d.ts` globally


:::tip
The `alchemy.run.ts` script will be run by `node` but still needs to infer the [Binding](/concepts/bindings) types which depends on `@cloudflare/workers-types`:
:::

```json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022"],
    "module": "ES2022",
    "moduleResolution": "bundler",
    "strict": true,
    "skipLibCheck": true,
    "types": ["@cloudflare/workers-types", "./types/env.d.ts"]
  },
  "include": ["types/**/*.ts", "alchemy.run.ts", "src/**/*.ts"]
}
``` 

### `vite.config.ts`

Use the `alchemyDevEnvironmentShim()` plugin to configure TanStack Start for local development:

```ts
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
import viteReact from "@vitejs/plugin-react";
import alchemy from "alchemy/cloudflare/tanstack-start";
import { defineConfig } from "vite";
import tsConfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  build: {
    target: "esnext",
    rollupOptions: {
      external: ["node:async_hooks", "cloudflare:workers"],
    },
  },
  plugins: [
    alchemy(),
    tsConfigPaths({
      projects: ["./tsconfig.json"],
    }),
    tanstackStart({
      target: "cloudflare-module",
      customViteReactPlugin: true,
    }),
    viteReact(),
  ],
});
```