Deploy TanStack Start to Cloudflare
Deploy a TanStack Start app with a server function to Cloudflare Workers.
Introduction
30 Second Summary
A web app can feel complete on your laptop while remaining invisible to everyone else. Putting it online often feels like a separate project.
In this project, you will take a TanStack Start full-stack app from local development to a public Cloudflare Workers deployment. A custom page will display the response from a server function.
What You'll Build
Your public app will load a custom page that displays a response produced by server code running on Cloudflare Workers.
By the end of this project, you'll have:
- A working local development app that loads in your browser before deployment.
- A custom full-stack page that displays data returned by server code.
- A public deployment whose traffic you can confirm through request logs in the Workers dashboard.
- An optional Secret Mission to push your full-stack deployment skills further.
Are there any prerequisites?
You will need Node.js installed on your computer. You will also need a free Cloudflare account plus access to a terminal.
Before We Start
A full-stack TanStack Start app needs a JavaScript runtime before it can run on your computer. Node.js provides that runtime.
You also need npm for project packages. A Cloudflare account gives you a destination for the deployed app.
In this step, get ready to:
- Get your terminal ready for local commands.
- Verify that Node.js includes npm.
- Prepare your Cloudflare account in a modern browser.
Open your terminal
The terminal is where you run the commands that create your app. Your operating system already includes a terminal application.
macOS
- Press Cmd+Space to open Spotlight Search.
- Type Terminal into the search field.
- Press Enter to open Terminal.
Windows
- Press the Windows key to open search.
- Type PowerShell into the search field.
- Press Enter to open PowerShell.
Linux
- Open your system application launcher.
- Search for Terminal.
- Select the terminal application from the results.
You are in. The command prompt means your terminal is ready to accept instructions.
Verify Node.js and npm
Node.js executes the JavaScript behind your local app. Its installer also includes npm for downloading project packages.
- Predict whether your computer already has both tools available.
- Check Node.js and npm by running these commands:
node --version
npm --version
What do these checks prove?
- The first command asks Node.js to print its installed version.
- The second command asks npm to print its installed version.
- Two version numbers confirm that your terminal can reach both tools.
✔️ I see two version numbers
You have the local runtime ready. Node.js can run the app while npm manages its packages.
ⓧ One or both commands fail
Your computer needs the Node.js LTS installer. The installer adds Node.js and npm together.
- Visit the official Node.js download page in your browser.
- Select the LTS release for your operating system.
The download page now shows the installer for your computer.
- Download the installer.
- Run the downloaded installer.
A system permission request during installation is normal. Approve it only when the installer came from the official Node.js page.
- Keep the default options on each installer screen.
- Finish the installation.
The installer confirms when Node.js has been added to your computer.
- Close your current terminal window.
macOS
- Press Cmd+Space to open Spotlight Search.
- Type Terminal into the search field.
- Press Enter to open a fresh terminal.
Windows
- Press the Windows key to open search.
- Type PowerShell into the search field.
- Press Enter to open a fresh terminal.
Linux
- Open your system application launcher.
- Search for Terminal.
- Select the terminal application from the results.
- Confirm the installation by running these commands:
node --version
npm --version
What does this confirm?
Each command prints the version installed on your computer. Two version numbers confirm that the installer added Node.js and npm to your terminal path.
That setup hurdle is cleared. Your terminal can now use both tools.
Still missing a version number?
Close every terminal window before opening a fresh one. An older terminal session may not detect newly installed tools.
Restart your computer if a fresh terminal still cannot find Node.js or npm.
Help me fix Node.js or npm after installation.
Prepare your Cloudflare account
Cloudflare uses your account to own the Worker that hosts your app. The same account later gives you access to deployment logs.
Account setup uses your email address and password. Your password stays on the official Cloudflare page linked below.
✔️ I already have an account
- Visit the Cloudflare dashboard in the browser you are using for this project.
- Enter your existing Cloudflare sign-in details.
- Submit the sign-in form.
- Confirm that your signed-in dashboard shows your account.
ⓧ I need to create an account
- Visit the official Cloudflare sign-up page in the browser you are using for this project.
- Enter your email address in the Email field.
- Enter a new password in the Password field.
- Select Create Account.
- Open the verification message that Cloudflare sends to your email address.
- Follow the verification link in the message.
- Return to the Cloudflare dashboard.
Why verify your email?
Cloudflare sends a verification message when you create an account. Verification confirms that you control the address connected to the account.
That account hurdle is cleared. Cloudflare is ready to receive your app when deployment time comes.
- Predict whether the terminal will recognize both local tools in the final check.
- Complete the final local check by running these commands:
node --version
npm --version
What does the final check prove?
The two commands test the runtime and its package manager from your current terminal session. Two version numbers show that your local tools are ready for the project.
You should see one Node.js version number followed by one npm version number.
Did one of the checks stop working?
Close the terminal before opening a fresh one. Restart your computer if the fresh session still cannot reach both tools.
Help me restore my Node.js and npm commands.
- Return to the signed-in Cloudflare dashboard in your browser.
You should see your dashboard with your account available. This confirms that your browser and Cloudflare account are ready.
Your computer and Cloudflare account are ready. Next up, you will scaffold the TanStack Start app and load it locally in your browser.
Scaffold the TanStack Start App
Before your app can call server code, it needs a working TanStack Start foundation. The scaffold supplies the project structure that later features build on.
This step uses Cloudflare's framework guide to prepare the app for Cloudflare Workers. A browser check proves the starter route works locally.
In this step, get ready to:
- Generate the Cloudflare-ready TanStack Start project.
- Confirm the generated project foundation.
- Open the starter page through a local development server.
Scaffold the Cloudflare-ready project
The create-cloudflare generator creates a framework project with Cloudflare-compatible configuration. It also installs the npm dependencies needed to run the app.
- Move to your Desktop by running this command:
cd ~/Desktop
What does this command do?
This command moves your terminal into the Desktop directory. The generator creates your project there so you can find it easily.
This first download can take a few minutes while npm fetches the generator and project dependencies.
- Approve the package installation if npm asks for permission.
- Create the tanstack-start-cloudflare-app project by running this command:
npm create cloudflare@latest tanstack-start-cloudflare-app -- --framework=tanstack-start --accept-defaults --no-deploy
What did the scaffold create?
- The --framework=tanstack-start option selects the TanStack Start framework.
- The --accept-defaults option uses the generator's default project choices.
- The --no-deploy option keeps the app local during this step.
- The generator creates the project files with installed npm dependencies and Cloudflare-compatible configuration.
When the terminal returns to its prompt, the scaffold has finished creating tanstack-start-cloudflare-app.
Did the scaffold stop early?
Confirm that your internet connection is active if the dependency download stops.
Remove any incomplete tanstack-start-cloudflare-app directory before running the scaffold command again.
Help me troubleshoot a create-cloudflare scaffold that stopped before installing its dependencies.
Check the generated foundation
A successful scaffold includes a project manifest and a starter route directory. Checking both paths confirms that the generator produced the foundation required for the next step.
- Confirm the generated foundation by running these checks:
ls tanstack-start-cloudflare-app/package.json
ls tanstack-start-cloudflare-app/src/routes
What are you checking?
- The package.json manifest contains the generated TanStack Start scripts and dependencies.
- The src/routes/ directory contains the generated starter page route.
You should see tanstack-start-cloudflare-app/package.json followed by the contents of tanstack-start-cloudflare-app/src/routes/. That confirms the project foundation is in place.
✔️ Awesome, I've got everything!
Great. Your generated manifest and starter route directory are ready.
ⓧ I'd like to double check the full code
- The tanstack-start-cloudflare-app directory is a scaffolded TanStack Start application with installed npm dependencies and the Cloudflare-compatible project configuration generated by Cloudflare's framework guide.
- The tanstack-start-cloudflare-app/package.json file is a generated project manifest containing TanStack Start scripts and dependencies.
- The tanstack-start-cloudflare-app/src/routes/ directory is a generated starter route directory containing the starter page route.
Run the starter app locally
A local development server runs the generated app on your computer. The process stays active in the terminal until you stop it with Ctrl+C.
- Move into the generated project directory by running this command:
cd tanstack-start-cloudflare-app
Why change directories?
The npm scripts live inside tanstack-start-cloudflare-app/package.json. Moving into that directory lets npm find the development script.
Before you run the app, what do you expect its first local page to show?
- Start the local development server by running this command:
npm run dev
What does this command do?
- The dev script starts the generated app in development mode.
- The terminal prints a local URL when the server is ready.
- The running process keeps serving the app while you work.
- Hold Cmd (macOS) or Ctrl (Windows) while clicking the local URL printed in your terminal.
You'll see the generated TanStack Start starter page in your browser on localhost. That page proves the starter route and local server are working.
You have your first visible win. Your Cloudflare-ready app now runs locally in the browser.
Does the starter page fail to load?
Keep the development server running while you open the local URL.
Use the URL printed by your current terminal session because the available local port can change.
Help me troubleshoot a TanStack Start development server that prints a local URL but does not load the starter page.
Your starter app is running locally. Next, you'll add a route that displays data returned by server code.
Add a Server-Powered Route
Your TanStack Start starter page proves that the app runs locally. The page does not yet demonstrate server-side logic.
This step adds a route that asks a server function for data before rendering. You will see that response in the browser at /server-data.
In this step, get ready to:
- Create the getServerMessage server function.
- Connect the /server-data route to the server function.
- Render the returned message in your local browser.
Create the server-powered route
A server function runs on the server while remaining callable from your route. The route loader collects its response before the page component renders.
- Create src/routes/server-data.tsx inside the existing tanstack-start-cloudflare-app folder by using your code editor's file explorer.
- Build the server-powered route by pasting this code into server-data.tsx:
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
const getServerMessage = createServerFn().handler(async () => {
// Return serializable data from server-side code
return { message: 'Hello from the server!' }
})
export const Route = createFileRoute('/server-data')({
// Fetch the server response before the page renders
loader: () => getServerMessage(),
component: ServerDataPage,
})
function ServerDataPage() {
// Read the response returned by the route loader
const serverData = Route.useLoaderData()
return (
<main>
<h1>Server-Powered Route</h1>
<p>{serverData.message}</p>
</main>
)
}
What does this code do?
- The createServerFn() call defines getServerMessage as server-side logic.
- The loader calls getServerMessage() when the route loads.
- The Route.useLoaderData() call gives the returned object to the page component.
- The component renders the object's message value inside the page.
Verify the local response
Before you load the new route, what message do you expect the browser to render?
- Save src/routes/server-data.tsx.
- Switch back to the localhost page from earlier.
- Replace the path after the local host and port with /server-data.
- Press Enter to load the route.
You should see the heading Server-Powered Route with the message Hello from the server!.
That is your first full-stack result working. The browser is now rendering data returned by your server function.
Route not loading?
- Confirm that the filename is exactly server-data.tsx inside src/routes.
- Check that createFileRoute('/server-data') matches the browser path.
- Check the terminal from earlier for the running local development server.
help me find why my TanStack Start /server-data route is not rendering
✔️ Awesome, I've got everything!
Your complete server-powered route is saved. The local page now proves that the route can render a server function response.
ⓧ I'd like to double check the full code
import { createFileRoute } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
const getServerMessage = createServerFn().handler(async () => {
// Return serializable data from server-side code
return { message: 'Hello from the server!' }
})
export const Route = createFileRoute('/server-data')({
// Fetch the server response before the page renders
loader: () => getServerMessage(),
component: ServerDataPage,
})
function ServerDataPage() {
// Read the response returned by the route loader
const serverData = Route.useLoaderData()
return (
<main>
<h1>Server-Powered Route</h1>
<p>{serverData.message}</p>
</main>
)
}
Your local full-stack route works. Next, you will authenticate with Cloudflare before deploying the app.
Log In with Wrangler
Your /server-data route now proves that TanStack Start can render a page locally. Its server function also returns data from the local runtime.
Deployment needs a trusted connection between your terminal and Cloudflare. Without that connection, the deployment command cannot act on your account.
Wrangler creates this connection through a browser-based OAuth login. You will then confirm the account that receives your app.
In this step, get ready to:
- Authorize Wrangler through Cloudflare's browser login flow.
- Confirm the authenticated Cloudflare account from your terminal.
Authorize Wrangler in your browser
OAuth lets you grant Wrangler access without typing your Cloudflare password into the terminal. Your browser handles the sign-in on Cloudflare's website.
- Return to the terminal from earlier.
- Stop the local development server by pressing Ctrl+C.
Your terminal prompt returns inside the existing tanstack-start-cloudflare-app project.
- Start the Cloudflare login flow by running this command:
npx wrangler login
What does this command do?
- The npx command runs Wrangler from your project's installed dependencies.
- The login flow asks Cloudflare to authorize Wrangler for your account.
- Wrangler opens the authorization page in your default browser.
- Complete the Cloudflare sign-in in your browser if prompted.
- Confirm the Cloudflare account shown on the authorization page.
- Approve Wrangler's access request.
- Return to the terminal after the browser confirms authorization.
That's the account link in place. Wrangler can now make authenticated requests for your deployment.
Browser did not open?
The terminal prints an authorization URL when the browser stays closed.
- Copy the authorization URL from the terminal.
- Paste the URL into your browser's address bar.
- Complete the Cloudflare authorization flow.
If the authorization still does not finish, help me troubleshoot the Wrangler browser login.
Confirm the authenticated account
The browser flow proves that authorization finished. The account check proves which Cloudflare account Wrangler uses.
Before you check, which Cloudflare account do you expect Wrangler to report?
- Retrieve the authenticated account information by running this command:
npx wrangler whoami
What does this command do?
- The whoami subcommand retrieves information about the current Wrangler user.
- A successful response confirms that Wrangler can use the stored authorization.
- The listed account identifies where your upcoming deployment runs.
You should see information for your authenticated user. You should also see the Cloudflare account that Wrangler can access.
Account information missing?
- Repeat the login command from the previous substep.
- Finish the browser approval before returning to the terminal.
- Run the account check again after the login completes.
If Wrangler still cannot find your account, help me diagnose the Wrangler authentication problem.
Wrangler is connected to your Cloudflare account. Next up, you will deploy the app and receive its public URL.
Deploy to Cloudflare Workers
Your /server-data route now displays the response from getServerMessage on your machine.
The next move is to package that same TanStack Start app for Cloudflare Workers.
Wrangler builds the app for the Workers runtime. It then publishes the result to a public workers.dev address.
In this step, get ready to:
- Prepare the existing project terminal for deployment.
- Build the application for the Workers runtime.
- Deploy the Worker to a public URL.
Prepare the deployment terminal
The deployment command must run inside tanstack-start-cloudflare-app. The terminal that launched your local development server is already in that directory.
- Switch back to the terminal that is running the local development server.
- Press Ctrl+C to stop the server.
- Check that the terminal prompt has returned inside tanstack-start-cloudflare-app.
Deploy the Worker
The project’s deployment script first creates a production build. Wrangler then uploads that build to your authenticated Cloudflare account.
- Follow the terminal instructions if Cloudflare asks you to set up a workers.dev subdomain.
Before you run this, do you expect the process to stop after the build or continue until your Worker has an address?
- Build the app and deploy the Worker by running this command:
npm run deploy
What does this command do?
- The first phase creates production output for the Workers runtime.
- The build includes the /server-data route with its getServerMessage server function.
- The second phase asks Wrangler to publish that output as the tanstack-start-cloudflare-app Worker.
You’ll see build output followed by Wrangler’s deployment result. The final lines include a public URL ending in workers.dev.
That is the hard part done. Your full-stack app is now running as a Cloudflare Worker.
- Record the public URL here: your workers.dev URL.
Deployment did not finish?
- Check that your terminal prompt is inside tanstack-start-cloudflare-app.
- Review the first build failure shown in the terminal before retrying the deployment.
- Retry the deployment after confirming that your internet connection is stable.
help me diagnose why my TanStack Start deployment to Cloudflare Workers did not finish.
Your Worker now has a public address. Next, you’ll test the server-powered route in production and confirm its requests in Cloudflare.
Verify the Live App
Your TanStack Start app has moved beyond localhost. Wrangler has already placed it on a public Cloudflare Worker.
A successful deployment message proves that your files reached Cloudflare. This step proves that the public page can run your server function.
In this step, get ready to:
- Open the public server-powered route.
- Generate a request that appears in the Worker logs.
Open the public server route
The address printed by Wrangler points to the deployed version of your app. Testing both the starter page and /server-data confirms that the full application reached the public URL.
- Switch back to the terminal from the deployment step.
- Find the public address that ends in workers.dev.
- Record that address here: your workers.dev URL.
- Switch back to the browser from your local test.
- Select the browser address bar.
- Paste your saved workers.dev URL.
- Press Enter.
You should see the deployed starter page at the public address. Your app is now loading from Cloudflare instead of localhost.
Before you check the custom route, do you think getServerMessage can respond when your browser is no longer using localhost?
- Select the browser address bar.
- Append /server-data to the address.
- Press Enter.
Your page should show the same response returned by getServerMessage during local testing. The public route is now executing its server function through the deployed Worker.
Public route not loading?
Confirm that the address starts with the complete URL printed by Wrangler. Check that the path ends with /server-data.
If the starter page also fails to load, return to the deployment terminal. Copy the full address ending in workers.dev again.
Ask for help with debugging why my deployed Cloudflare Worker URL or /server-data route is not loading.
Watch the request reach Cloudflare
Workers Logs record each invocation handled by your deployed Worker. A request for /server-data gives you direct evidence that traffic reached the server.
- Open a new browser tab.
- Go to the Cloudflare dashboard.
- Select your Cloudflare account if prompted.
- Select Workers & Pages from the left sidebar.
- Select tanstack-start-cloudflare-app from Overview.
- Select Logs.
- Select Live from the right-hand navigation.
Before you generate another request, do you expect the route refresh to appear in the live log stream?
- Switch to the browser tab showing the public /server-data route.
- Refresh the page.
- Return to the Live logs tab.
The log stream may need a few seconds to display the request. You should see a fresh request entry with a URL ending in /server-data.
That request confirms that the public page reached your Worker. The dashboard now gives you a place to inspect future traffic.
Request missing from the logs?
Keep Live selected before refreshing the public route again. Confirm that the refreshed address ends in workers.dev/server-data instead of using localhost.
Ask for help with finding my /server-data request in Cloudflare Worker live logs.
You have confirmed the full production loop. Your public route runs getServerMessage.
That is the final check complete. Cloudflare can now show you every request that reaches your deployed app.
Secret mission
Run a Production Smoke Test
Turn your successful deployment into a repeatable production check. Test the public routes and connect the server-powered response to a fresh Worker request log.
Clean Up Your Resources
Clean Up Your Resources
Your cleanup choices cover a local folder with no ongoing cloud usage plus a public deployment on Cloudflare Workers under your account's billing rules. Decide whether to keep building, pause local work, or delete both resources.
Cost warning
Cloudflare Workers usage follows the plan attached to your account.
- Review your current plan and usage before leaving the Worker deployed.
Resources you used:
- Cloudflare Worker named tanstack-start-cloudflare-app serving the public workers.dev URL.
- tanstack-start-cloudflare-app project folder containing your TanStack Start source code plus its installed dependencies.
Keep everything running
No action needed. Choose this if you are still actively building or want to keep sharing the public app.
- Keep the tanstack-start-cloudflare-app folder on your computer.
- Leave the tanstack-start-cloudflare-app Worker deployed.
The public workers.dev URL continues serving your app. The /server-data route continues displaying the response from getServerMessage.
Pause - I'll come back to this later
Shut down the local development server to free up memory. Your project files stay on disk while the deployed Worker remains online.
- Return to the terminal panel running the local development server if it is still active.
- Press Ctrl+C to stop the local development server.
- Leave the tanstack-start-cloudflare-app folder on your computer.
- Leave the tanstack-start-cloudflare-app Worker deployed.
Your localhost page stops responding after the server closes. The public workers.dev URL remains online.
Delete - I don't want to use this again
Remove the deployed Worker plus the local project folder when you want to start fresh. You stay in control because the local folder remains untouched until the final command.
- Copy any source code you want to keep to a separate location.
- Return to the tanstack-start-cloudflare-app Worker page in the Cloudflare dashboard from earlier.
- Use the deletion option on that Worker page to delete tanstack-start-cloudflare-app.
- Confirm the deletion when Cloudflare asks.
- Return to the public workers.dev URL from earlier in your browser.
You'll see that the URL no longer serves your application. The public app is now offline while your local source code remains safe.
- Return to the terminal panel running the local development server if it is still active.
- Press Ctrl+C to stop the local development server.
- Use Finder on macOS or File Explorer on Windows to find the existing tanstack-start-cloudflare-app folder.
- Record the folder's full path here: path to tanstack-start-cloudflare-app.
macOS
- Check that path to tanstack-start-cloudflare-app points to the exact project folder.
- Delete the local project folder by running this command:
rm -rf "[[PROJECT_FOLDER_PATH="path to tanstack-start-cloudflare-app"]]"
What does this command do?
The rm -rf command permanently removes the folder path you entered plus everything inside it.
- Return to the folder's previous location in Finder.
You should no longer see the tanstack-start-cloudflare-app folder.
Windows
- Check that path to tanstack-start-cloudflare-app points to the exact project folder.
- Delete the local project folder by running this command:
rmdir /s /q "[[PROJECT_FOLDER_PATH="path to tanstack-start-cloudflare-app"]]"
What does this command do?
The rmdir /s /q command permanently removes the folder path you entered plus everything inside it.
- Return to the folder's previous location in File Explorer.
You should no longer see the tanstack-start-cloudflare-app folder.
Cleanup complete. The public Worker plus the local project folder are now removed.
Nice Work!
Nice Work!
Great job! Your TanStack Start app now runs on Cloudflare Workers at a public URL.
You've learned how to:
- Create a local development loop for a full-stack app. Confirm the starter page in your browser.
- Build a server-powered route at /server-data. Render the response from the getServerMessage server function in the browser.
- Authenticate Wrangler with your Cloudflare account. Publish a live deployment. Confirm incoming requests through Worker logs.
- Secret Mission: Apply your full-stack deployment skills in an optional project extension that pushes your app further.
Ready to quiz yourself?