# TanStack Start (/docs/frameworks/tanstack-start)



<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npx shadcn@latest add @uploadcn/file-upload @uploadcn/upload-route-tanstack
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm dlx shadcn@latest add @uploadcn/file-upload @uploadcn/upload-route-tanstack
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn dlx shadcn@latest add @uploadcn/file-upload @uploadcn/upload-route-tanstack
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun x shadcn@latest add @uploadcn/file-upload @uploadcn/upload-route-tanstack
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Server route [#server-route]

```ts title="src/routes/api/upload.ts"
import { createFileRoute } from "@tanstack/react-router"
import { createUploadRoute, s3Storage } from "@uploadcn/server"

const upload = createUploadRoute({
  storage: s3Storage({
    bucket: process.env.S3_BUCKET!,
    region: process.env.S3_REGION!,
    accessKeyId: process.env.S3_ACCESS_KEY_ID!,
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  }),
})

export const Route = createFileRoute("/api/upload")({
  server: {
    handlers: {
      POST: ({ request }) => upload.POST(request),
    },
  },
})
```

## Components [#components]

Components are identical to Next.js. Nothing in UploadCN depends on a framework:

```tsx title="src/routes/index.tsx"
import { createFileRoute } from "@tanstack/react-router"

import { FileUpload } from "@/components/file-upload"

export const Route = createFileRoute("/")({
  component: () => <FileUpload maxFiles={5} />,
})
```
