Instruction file imported from sirgawain0x/creative-pixels (
.cursor/rules/tanstack-hosting.mdc). Copyright stays with the author.
id: hosting title: Hosting
Hosting is the process of deploying your application to the internet so that users can access it. This is a critical part of any web development project, ensuring your application is available to the world. TanStack Start is built on Vite, a powerful dev/build platform that allows us to make it possible to deploy your application to any hosting provider.
What should I use?
TanStack Start is designed to work with any hosting provider, so if you already have a hosting provider in mind, you can deploy your application there using the full-stack APIs provided by TanStack Start.
However, since hosting is one of the most crucial aspects of your application's performance, reliability, and scalability, we recommend using one of our Official Hosting Partners: Cloudflare, Netlify, or Railway.
Deployment
Once you've chosen a deployment target, you can follow the deployment guidelines below to deploy your TanStack Start application to the hosting provider of your choice:
cloudflare-workers: Deploy to Cloudflare Workersnetlify: Deploy to Netlifyrailway: Deploy to Railwaynitro: Deploy using Nitrovercel: Deploy to Vercelnode-server: Deploy to a Node.js serverbun: Deploy to a Bun serverappwrite-sites: Deploy to Appwrite Sites- ... and more to come!
Cloudflare Workers ⭐ Official Partner
When deploying to Cloudflare Workers, you'll need to complete a few extra steps before your users can start using your app.
- Install
@cloudflare/vite-pluginandwrangler
pnpm add -D @cloudflare/vite-plugin wrangler
- Add the Cloudflare plugin to your
vite.config.tsfile
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { cloudflare } from '@cloudflare/vite-plugin'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
cloudflare({ viteEnvironment: { name: 'ssr' } }),
tanstackStart(),
viteReact(),
],
})
- Add a
wrangler.jsoncconfig file
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "tanstack-start-app",
"compatibility_date": "2025-09-02",
"compatibility_flags": ["nodejs_compat"],
"main": "@tanstack/react-start/server-entry"
}
- Modify the scripts in your
package.jsonfile
{
"scripts": {
"dev": "vite dev",
"build": "vite build && tsc --noEmit",
// ============ 👇 remove this line ============
"start": "node .output/server/index.mjs",
// ============ 👇 add these lines ============
"preview": "vite preview",
"deploy": "npm run build && wrangler deploy",
"cf-typegen": "wrangler types"
}
}
- Login with Wrangler to authenticate with your Cloudflare account.
npx wrangler login
or if using pnpm:
pnpm dlx wrangler login
To check current user use wrangler whoami.
- Deploy
pnpm run deploy
Deploy your application to Cloudflare Workers using their one-click deployment process, and you're ready to go!
A full TanStack Start example for Cloudflare Workers is available here.
Netlify ⭐ Official Partner
Install and add the @netlify/vite-plugin-tanstack-start plugin, which configures your build for Netlify deployment and provides full Netlify production platform emulation in local dev:
npm install --save-dev @netlify/vite-plugin-tanstack-start
# or...
pnpm add --save-dev @netlify/vite-plugin-tanstack-start
# or yarn, bun, etc.
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import netlify from '@netlify/vite-plugin-tanstack-start' // ← add this
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
tanstackStart(),
netlify(), // ← add this (anywhere in the array is fine)
viteReact(),
],
})
Finally, use Netlify CLI to deploy your app:
npx netlify deploy
If this is a new Netlify project, you'll be prompted to initialize it and build settings will be automatically configured for you.
For more detailed documentation, check out the full TanStack Start on Netlify docs.
Manual configuration
Alternatively, if you prefer manual configuration, you can add a netlify.toml file to your project root:
[build]
command = "vite build"
publish = "dist/client"
[dev]
command = "vite dev"
port = 3000
Or you can set the above settings directly in the Netlify app.
Other deployment methods
Netlify also supports other deployment methods, such as continuous deployment from a git repo hosted on GitHub, GitLab, or others, starting from a template, deploying or importing from an AI code generation tool, and more.
Railway ⭐ Official Partner
Railway provides instant deployments with zero configuration. Follow the Nitro deployment instructions, then deploy to Railway:
-
Push your code to a GitHub repository
-
Connect your repository to Railway at railway.com
-
Railway will automatically detect your build settings and deploy your application
Railway automatically provides:
- Automatic deployments on every push to your repository
- Built-in databases (Postgres, MySQL, Redis, MongoDB)
- Preview environments for pull requests
- Automatic HTTPS and custom domains
For more details, see Railway's documentation.
Nitro
Nitro is an agnostic layer that allows you to deploy TanStack Start applications to a wide range of hostings.
⚠️ The nitro/vite plugin natively integrates with Vite Environments API as the underlying build tool for TanStack Start. It is still under active development and receives regular updates. Please report any issues you encounter with reproduction so they can be investigated.
install the nightly version of nitro by specifying the following in your package.json
"nitro": "npm:nitro-nightly@latest"
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { defineConfig } from 'vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [tanstackStart(), nitro(), viteReact()],
})
Performance Tip: FastResponse
If you're deploying to Node.js with Nitro (which uses srvx under the hood), you can get a ~5% throughput improvement by replacing the global Response constructor with srvx's optimized FastResponse.
First, install srvx:
npm install srvx
Then add this to your server entry point (src/server.ts):
import { FastResponse } from 'srvx'
globalThis.Response = FastResponse
This works because srvx's FastResponse includes an optimized _toNodeResponse() path that avoids the overhead of the standard Web Response to Node.js conversion. This optimization only applies to Node.js deployments using Nitro/h3/srvx.
Vercel
Follow the Nitro deployment instructions.
Deploy your application to Vercel using their one-click deployment process, and you're ready to go!
Node.js / Docker
Follow the Nitro deployment instructions. Use the node command to start your application from the server from the build output files.
Ensure build and start npm scripts are present in your package.json file:
"build": "vite build",
"start": "node .output/server/index.mjs"
Then you can run the following command to build your application:
npm run build
You can start your application by running:
npm run start
Bun
[!IMPORTANT] Currently, the Bun specific deployment guidelines only work with React 19. If you are using React 18, please refer to the Node.js deployment guidelines.
Make sure that your react and react-dom packages are set to version 19.0.0 or higher in your package.json file. If not, run the following command to upgrade the packages:
bun install react@19 react-dom@19
Follow the Nitro deployment instructions.
Depending on how you invoke the build, you might need to set the 'bun' preset in the Nitro configuration:
// vite.config.ts
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import { defineConfig } from 'vite'
import { nitro } from 'nitro/vite'
import viteReact from '@vitejs/plugin-react'
export default defineConfig({
plugins: [tanstackStart(), nitro({ preset: 'bun' }), viteReact()],
})
Production Server with Bun
Alternatively, you can use a custom server implementation that leverages Bun's native APIs.
We provide a reference implementation that demonstrates one approach to building a production-ready Bun server. This example uses Bun-native functions for optimal performance and includes features like intelligent asset preloading and memory management.
This is a starting point - feel free to adapt it to your needs or simplify it for your use case.
What this example demonstrates:
- Serving static assets using Bun's native file handling
- Hybrid loading strategy (preload small files, serve large files on-demand)
- Optional features like ETag support and Gzip compression
- Production-ready caching headers
Quick Setup:
-
Copy the
server.tsfile from the example repository to your project root (or use it as inspiration for your own implementation) -
Build your application:
bun run build -
Start the server:
bun run server.ts
Configuration (Optional):
The reference server implementation includes several optional configuration options via environment variables. You can use these as-is, modify them, or remove features you don't need:
# Basic usage - just works out of the box
bun run server.ts
# Common configurations
PORT=8080 bun run server.ts # Custom port
ASSET_PRELOAD_VERBOSE_LOGGING=true bun run server.ts # See what's happening
Available Environment Variables:
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 3000 |
ASSET_PRELOAD_MAX_SIZE |
Maximum file size to preload into memory (bytes) | 5242880 (5MB) |
ASSET_PRELOAD_INCLUDE_PATTERNS |
Comma-separated glob patterns for files to include | All files |
ASSET_PRELOAD_EXCLUDE_PATTERNS |
Comma-separated glob patterns for files to exclude | None |
ASSET_PRELOAD_VERBOSE_LOGGING |
Enable detailed logging | false |
ASSET_PRELOAD_ENABLE_ETAG |
Enable ETag generation | true |
ASSET_PRELOAD_ENABLE_GZIP |
Enable Gzip compression | true |
ASSET_PRELOAD_GZIP_MIN_SIZE |
Minimum file size for Gzip (bytes) | 1024 (1KB) |
ASSET_PRELOAD_GZIP_MIME_TYPES |
MIME types eligible for Gzip | text/,application/javascript,application/json,application/xml,image/svg+xml |
# Optimize for minimal memory usage
ASSET_PRELOAD_MAX_SIZE=1048576 bun run server.ts
# Preload only critical assets
ASSET_PRELOAD_INCLUDE_PATTERNS="*.js,*.css" \
ASSET_PRELOAD_EXCLUDE_PATTERNS="*.map,vendor-*" \
bun run server.ts
# Disable optional features
ASSET_PRELOAD_ENABLE_ETAG=false \
ASSET_PRELOAD_ENABLE_GZIP=false \
bun run server.ts
# Custom Gzip configuration
ASSET_PRELOAD_GZIP_MIN_SIZE=2048 \
ASSET_PRELOAD_GZIP_MIME_TYPES="text/,application/javascript,application/json" \
bun run server.ts
Example Output:
📦 Loading static assets from ./dist/client...
Max preload size: 5.00 MB
📁 Preloaded into memory:
/assets/index-a1b2c3d4.js 45.23 kB │ gzip: 15.83 kB
/assets/index-e5f6g7h8.css 12.45 kB │ gzip: 4.36 kB
💾 Served on-demand:
/assets/vendor-i9j0k1l2.js 245.67 kB │ gzip: 86.98 kB
✅ Preloaded 2 files (57.68 KB) into memory
🚀 Server running at http://localhost:3000
For a complete working example, check out the TanStack Start + Bun example in this repository.
Appwrite Sites
When deploying to Appwrite Sites, you'll need to complete a few steps:
- Create a TanStack Start app (or use an existing one)
npm create @tanstack/start@latest
- Push your project to a GitHub repository
Create a GitHub repository and push your code.
- Create an Appwrite project
Head to Appwrite Cloud and sign up if you haven't already, then create your first project.
- Deploy your site
In your Appwrite project, navigate to the Sites page from the sidebar. Click on the Create site, select Connect a repository, connect your GitHub account and select your repository.
-
Select the production branch and root directory
-
Verify TanStack Start is selected as the framework
-
Confirm the build settings:
- Install command:
npm install - Build command:
npm run build - Output directory:
./dist(if you're using Nitro v2 or v3, this should be./.output)
- Install command:
-
Add any required environment variables
-
Click Deploy
After successful deployment, click the Visit site button to see your deployed application.