---
title: "How to deploy a TanStack Start app in 2026: Nitro, a start script and one command | Pethost"
description: "Deploy TanStack Start on a Node server: add Nitro and a start script, run pethost deploy, and the app is online over HTTPS in 29 seconds, for €9.99 a month."
---

[Blog](https://pethost.dev/blog/) · Deploy guides

# How to deploy a TanStack Start app in 2026: Nitro, a start script and one command

By the Pethost team · 10 October 2026 · 8 min read

You have a TanStack Start app, and you want it on a Node server at an address with HTTPS. TanStack's hosting guide asks two things of the app for that: the Nitro plugin, and a `start` script. With both in place, `pethost deploy` writes the Dockerfile, builds the app and prints its address. The app the TanStack CLI creates was built and started in 29 seconds the first time.

**In short**

- **Two things in the app:** the Nitro plugin, which `--deployment nitro` adds when the app is created, and `"start": "node .output/server/index.mjs"` in `package.json`.
- **One command:** `pethost deploy` in the folder that has `package.json`. It writes a Dockerfile that runs `npm run build` and then `npm run start`.
- **The port:** the Nitro server listens on 3000. Pethost finds that and sends the address there, over HTTPS.
- **A build that fails changes nothing:** the version before keeps running, and the screen shows the build's error.
- **The price:** €9.99 a month for a machine of 2 vCPU, 3 GB and 30 GB that runs this app and every other project you have. There is no free tier.

## What you need to deploy a TanStack Start app in 2026

Three things: the app, the `pethost` command and a Pethost account.

**The app** here is the one the TanStack CLI creates, with Nitro as its deployment target:

```
npx @tanstack/cli@latest create my-app --deployment nitro
```

The flag adds the Nitro plugin to `vite.config.ts`. In an app you already have, add it as the hosting guide's Nitro part says:

```
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()],
})
```

Then give `package.json` the script that starts what the build writes. The CLI leaves `build` there and no `start`:

```
"scripts": {
  "dev": "vite dev --port 3000",
  "build": "vite build",
  "start": "node .output/server/index.mjs"
}
```

**The command** is one program, installed by one line. Every command it has is in the [CLI's reference](https://pethost.dev/docs/cli/).

```
curl -fsSL https://pethost.dev/install.sh | sh      # macOS, Linux
irm https://pethost.dev/install.ps1 | iex           # Windows, in PowerShell
```

**The account** needs a plan. If you are not signed in, `pethost deploy` opens your browser and signs you in. If you have no plan yet, it shows you where to choose one, and waits.

## Deploy the TanStack Start app with one command

Go to the folder that has `package.json` and run `pethost deploy`. This is the whole screen, for the app the CLI created:

```
$ cd my-app
$ pethost deploy
Name it [my-app]:    it will live at https://my-app.sam.pethost.app
✓ Packed 18 files, 183 KB   (left out node_modules)
✓ Uploaded straight to your machine
✗ /compose.yaml: the project directory has no compose.yaml at its root: add one
✓ Node.js project detected, wrote Dockerfile.
✓ Packed 19 files, 184 KB   (left out node_modules)
✓ Uploaded straight to your machine
✓ Built and started in 29 s
  · wrote compose.yaml for the Dockerfile: the service app, reading .env
✓ app listens on 3000 → https://my-app.sam.pethost.app
  It answers 200.

https://my-app.sam.pethost.app

Wrote .pethost (commit it). Next:   pethost logs -f   ·   pethost open
```

1. **It asks one thing** The project's name, which is the first word of its address. Enter takes the folder's name.
2. **The machine finds nothing to run** The folder goes straight to your machine, without `node_modules`. The line with the cross is its answer: a project runs from a Dockerfile or a Compose file, and the folder has neither yet.
3. **pethost writes the Dockerfile** It read the `build` and `start` scripts in `package.json`, and uploads the folder again.
4. **The machine builds and starts it** It sees that the server listens on 3000 and sends the address there. Then pethost asks the address itself, and prints what it answered: 200.

We asked the deployed app what a visitor asks. The home page and `/about` each answered 200 with server-rendered HTML, and an address with no route answered 404. The running server took 43 MB of memory.

## The Dockerfile that pethost writes for TanStack Start

This is the file as it was written into the app's folder, whole:

```
# Written by pethost deploy for this Node.js project: Node 24 (no .nvmrc names another),
# npm installs it (package-lock.json), package.json builds it with "vite build",
# package.json starts it with "node .output/server/index.mjs".
# It is yours now: change it as you like. pethost does not write it again.

FROM node:24
WORKDIR /app

COPY . .

# Every dependency: what builds the project, and may start it, is among the ones for
# development.
RUN --mount=type=cache,target=/root/.npm \
    npm install

RUN npm run build

ENV NODE_ENV=production
CMD ["npm", "run", "start"]
```

Its first lines say what pethost read in your folder. The package manager is the one your lockfile names, and the Node version is the one `.nvmrc` or `.node-version` names, or Node 24 where there is neither. The build and the start are your two scripts, as you wrote them.

### Without the start script

A TanStack Start app can be built for several kinds of host, so pethost does not guess how yours starts. Without a `start` script it writes no file and says why:

```
$ pethost deploy
Name it [my-app]:    it will live at https://my-app.sam.pethost.app
✓ Packed 13 files, 177 KB
✓ Uploaded straight to your machine
✗ /compose.yaml: the project directory has no compose.yaml at its root: add one
  package.json builds the project and names nothing that starts it (no start script), and what it builds is no site of a kind pethost has a row for.
  Your coding agent writes one in a minute: "Write a Dockerfile for this app".
  Then run pethost deploy again.     How Pethost runs a folder: https://pethost.dev/docs/api/#CreateProject
```

Add the script and run the command again.

## Change a route and deploy again

Edit a route and run the same command. The second deploy took 7 seconds, because the machine keeps the build's layers and npm's cache:

```
$ pethost deploy
my-app (.pethost)
✓ Packed 20 files · uploaded · built and started in 7 s
  · wrote compose.yaml for the Dockerfile: the service app, reading .env
  · kept the project's x-pethost
  It answers 200.
https://my-app.sam.pethost.app
```

### When the build fails

We broke a route file to see it. The screen shows the build's log with the error in it, and the last line says what visitors get. This is that screen, shortened to three of its lines:

```
$ pethost deploy
my-app (.pethost)
✗ Deploy failed: failed to build: failed to solve: process "/bin/sh -c npm run build" did not complete successfully: exit code: 1
    #9 0.793 Error: Error transforming route file /app/src/routes/about.tsx: SyntaxError: Unexpected token, expected "," (4:19)
  Nothing changed: the version before still runs.
```

To deploy on every push, connect the repository once with `pethost github sam/my-app`. Pethost reads only the repositories you gave its GitHub App. `pethost rollback` puts the version before the current one back, and your machine keeps the three versions before it. An AI agent can do all of this for you through Pethost's MCP server: [how an agent deploys and looks after a project](https://pethost.dev/blog/hosting-for-ai-coding-agents/).

## Environment variables and your own domain

A variable that a server function reads is one command. It asks for the value without showing it, puts it into the project's `.env` file on the machine, and later deploys keep it:

```
pethost env set DATABASE_URL
```

Any name under your account's domain is an address at once, with HTTPS. A domain you own takes one command and one DNS record:

```
pethost domain add app.example.com
```

The command prints the record to make: a CNAME from your name to your machine's name. The certificate comes by itself once the name resolves, and renews itself.

## What you get for the price

Pethost is €9.99 a month for everything you host, on 2 vCPU, 3 GB of memory and 30 GB of disk. The app's server took 43 MB of that memory, so the machine has room for its database, a worker and your other projects, such as a [React Router app](https://pethost.dev/blog/deploy-react-router-app/) beside it. There is [no fee per project](https://pethost.dev/blog/unlimited-projects-flat-monthly-fee/) and [nothing metered](https://pethost.dev/blog/paas-without-usage-based-billing/): server functions are not billed by the call.

- **€9.99** a month for the whole machine
- **29 s** to build and start the app, the first time
- **7 s** for the deploy after it

What is already done on it: HTTPS with certificates that renew themselves, deploys from GitHub, nightly backups kept for 14 days, SSH into any container, and every request counted, with the busiest paths and the error rate of the last 30 days. The machine is always on, so a server function [never waits for a cold start](https://pethost.dev/blog/always-on-hosting-no-cold-starts/). The plans are on the [pricing](https://pethost.dev/#pricing) part of the first page.

**One project, open on its requests.** How many came, how fast they were answered, and a chart of the last 15 minutes.

![The Pethost panel: one project open on its requests, with their count, their response times and a chart of the last 15 minutes.](https://pethost.dev/shots/project.webp)

### Pethost is the best pick for

- **Developers with a full-stack React app**: the server, its server functions and its database on one machine, on one bill
- **Solo developers** with several side projects, each at an address of its own
- **People whose agent deploys for them**: Claude Code or Codex puts the app online and reads its logs
- **Early startups** who want a fixed monthly cost while the product is small

### Look elsewhere if

- Your application needs several regions or autoscaling

## Questions

### How do I run TanStack Start on a Node server?

Add the Nitro plugin to `vite.config.ts` and the script `"start": "node .output/server/index.mjs"` to `package.json`, as TanStack's hosting guide says. `npm run build` then writes the server into `.output`, and `npm run start` runs it on port 3000.

### Does a TanStack Start app need a Dockerfile to deploy?

On Pethost a project runs from a Dockerfile or a Compose file, and you do not have to write it: once `package.json` has a `build` and a `start` script, `pethost deploy` writes the Dockerfile and deploys it. The file stays in your folder, and you can change it.

### What happens when a TanStack Start build fails on deploy?

Nothing changes for visitors. The deploy stops, the screen shows the build's log with the error, and the version that ran before keeps running.

### Can I deploy a TanStack Start app from GitHub on every push?

Yes. Deploy the folder once with `pethost deploy`, then run `pethost github owner/repository`. From then on every push to the repository deploys itself, and `pethost rollback` goes back to an earlier commit.

### What does it cost to host a TanStack Start app on Pethost?

€9.99 a month for the Starter machine of 2 vCPU, 3 GB and 30 GB, with no fee per project and no charge per request: the same machine runs your other apps, sites and databases. There is no free tier. Prices are without VAT.

The screens are deploys of the app that `npx @tanstack/cli@latest create --deployment nitro` writes, with TanStack Start 1.168.61, Nitro 3.0.260610-beta and pethost 0.2.1, on a test machine of ours that had built nothing before. The account in them is the example one, `sam`.

1. [TanStack Start: hosting](https://tanstack.com/start/latest/docs/framework/react/guide/hosting)
2. [TanStack Start: quick start](https://tanstack.com/start/latest/docs/framework/react/quick-start)
3. [pethost, the command line of Pethost](https://pethost.dev/docs/cli/)

## Put your projects online today

A machine of your own, as many projects as fit, one flat price. Nothing metered, nothing billed on top.

[Host all your projects for €9.99/mo](https://console.pethost.dev/)

## Keep reading

- 10 October 2026 [How to deploy a VitePress site in 2026: one command, HTTPS and a Dockerfile you keep](https://pethost.dev/blog/deploy-vitepress-site/) Deploy a VitePress site with one command: pethost deploy writes the Dockerfile, builds the site and serves it over HTTPS, on a machine that is €9.99 a month.
- 10 October 2026 [How to deploy an Eleventy site in 2026: one command, HTTPS and a Dockerfile you keep](https://pethost.dev/blog/deploy-eleventy-site/) Deploy an Eleventy (11ty) site with one command: pethost deploy writes the Dockerfile, builds _site and serves it over HTTPS, on a machine for €9.99 a month.
- 10 October 2026 [How to self-host RSSHub in 2026: its Compose file, one command and HTTPS](https://pethost.dev/blog/self-host-rsshub/) Self-host RSSHub with its own Docker Compose file, unchanged: run pethost deploy and get HTTPS, with Redis and Browserless running, for €9.99 a month.
- 10 October 2026 [How to self-host Umami in 2026: its Compose file, one command and HTTPS](https://pethost.dev/blog/self-host-umami/) Self-host Umami analytics with its own Docker Compose file: set two secrets, run pethost deploy, get HTTPS, Postgres and nightly backups for €9.99 a month.

[All articles](https://pethost.dev/blog/) · [About Pethost](https://pethost.dev/about/) · [Pricing](https://pethost.dev/#pricing)

Pethost · Stephan Gomer · NIP 1133096755

[Home](https://pethost.dev/) [About](https://pethost.dev/about/) [Blog](https://pethost.dev/blog/) [Terms](https://pethost.dev/terms/) [Privacy](https://pethost.dev/privacy/) [Refunds](https://pethost.dev/refunds/) [support@pethost.dev](mailto:support@pethost.dev)
