---
title: TanStack Start, Nuxt and other Nitro apps
description: Deploy TanStack Start, Nuxt, SolidStart and other Nitro apps as a Node.js server, with the server preset set to node-server.
---

TanStack Start, Nuxt, SolidStart, Analog and plain Nitro projects all build their server with [Nitro](https://nitro.build). Nitro can compile the same app for many hosts, and the host it targets is called the **server preset**.

ZevCloud runs your app as a Node.js server, so the preset has to be **`node-server`**. A build for another host (Cloudflare Workers, Vercel, Netlify and similar) still builds successfully, but its output only exports a request handler and never starts a server. On ZevCloud it starts, exits straight away with no error in the logs, and is eventually stopped for crashing repeatedly.

## Settings at a glance

| Setting | Value |
| --- | --- |
| Server preset | `node-server` |
| Build command | `npm run build` (or your package manager's equivalent) |
| Start command | `node .output/server/index.mjs` |
| Port | `3000`, read from the `PORT` environment variable |

ZevCloud fills these in when it detects TanStack Start or Nuxt. If you set your own start command, keep it pointing at `.output/server/index.mjs`.

## Set the server preset to node-server

Set the preset in your project's config, commit, and redeploy. Pick the section for your framework.

### TanStack Start

The config API changed between versions. Check the version of `@tanstack/react-start` (or `@tanstack/solid-start`) in your `package.json` and use the matching snippet.

**Version 1.132 and later.** Nitro is a separate Vite plugin. Set the preset on it in `vite.config.ts`:

```ts
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import viteReact from '@vitejs/plugin-react'
import { nitro } from 'nitro/vite'

export default defineConfig({
  plugins: [tanstackStart(), nitro({ preset: 'node-server' }), viteReact()],
})
```

If your project uses the Nitro v2 plugin instead, the option is the same:

```ts
// vite.config.ts
import { nitroV2Plugin } from '@tanstack/nitro-v2-vite-plugin'

// ...
  plugins: [tanstackStart(), nitroV2Plugin({ preset: 'node-server' }), viteReact()],
```

If `vite.config.ts` has no Nitro plugin and uses `@cloudflare/vite-plugin` instead, the project is set up as a Cloudflare Worker. Remove that plugin, install `nitro`, and add `nitro({ preset: 'node-server' })` as above.

**Versions 1.121 to 1.131.** Nitro is built into the TanStack Start plugin and the preset is its `target` option:

```ts
// vite.config.ts
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'

export default defineConfig({
  plugins: [tanstackStart({ target: 'node-server' })],
})
```

**Version 1.120 and earlier (Vinxi, `app.config.ts`).** The preset is `server.preset`:

```ts
// app.config.ts
import { defineConfig } from '@tanstack/react-start/config'

export default defineConfig({
  server: { preset: 'node-server' },
})
```

### Nuxt

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server',
  },
})
```

### Other Nitro apps

SolidStart (`app.config.ts`):

```ts
// app.config.ts
import { defineConfig } from '@solidjs/start/config'

export default defineConfig({
  server: { preset: 'node-server' },
})
```

Plain Nitro (`nitro.config.ts`). Nitro 2 imports from `nitropack/config`, Nitro 3 from `nitro`:

```ts
// nitro.config.ts (Nitro 2)
import { defineNitroConfig } from 'nitropack/config'

export default defineNitroConfig({
  preset: 'node-server',
})
```

```ts
// nitro.config.ts (Nitro 3)
import { defineConfig } from 'nitro'

export default defineConfig({
  preset: 'node-server',
})
```

### What about the NITRO_PRESET variable?

ZevCloud builds every Node.js service with the build variable `NITRO_PRESET=node-server`, including services where no framework was detected. It usually appears in the **Variables** tab, and services created before this default get it on their next deploy if they don't already have one. Apps that don't use Nitro ignore it.

It fixes the common case: a TanStack Start or Nuxt project whose config falls back to Cloudflare or Vercel when nothing says otherwise. We've confirmed it on such a TanStack Start project: the same commit built `cloudflare-module` without the variable and `node-server` with it.

It can't override a preset that's hard-coded in your config, such as `nitro: { preset: 'cloudflare-module' }` in `nuxt.config.ts`, `tanstackStart({ target: 'cloudflare-module' })`, or `nitro({ preset: 'cloudflare-module' })` on the Nitro Vite plugin. If your config names a preset, change it there to `node-server`.

To use a different preset on purpose, set `NITRO_PRESET` yourself in the **Variables** tab. ZevCloud never replaces a value you set.

## Listen on PORT

Nitro's `node-server` output reads the `PORT` environment variable and listens on all interfaces, which is what ZevCloud needs. ZevCloud sets `PORT` for you. Don't set `HOST` or `NITRO_HOST` to `127.0.0.1` or `localhost`: the app would then only accept connections from inside its own container.

## Check which preset a build used

Open the deployment's build log on the **Deployments** tab and look for Nitro's build line:

```text
Building Nitro Server (preset: `node-server`, compatibility date: `2024-11-01`)
```

Nuxt prints `Building Nuxt Nitro server (preset: ...)`, newer Nitro prints `Building [Nitro] (preset: ...)`, and Vinxi prints `Preparing app for node-server...`. The same name is saved in `.output/nitro.json` after a local build.

If a build targets another host, ZevCloud marks the deployment with an amber **Built for ...** notice before the app has a chance to crash, and the crash-loop email and dashboard name the build target if it does.

## Using an AI coding assistant?

> **Tip: Copy this prompt into your AI assistant**
>
> If an AI tool (Cursor, Claude, ChatGPT, Lovable, Bolt and similar) set up your project, it may have targeted Cloudflare or Vercel by default. Give it this prompt:
>
> ```text
> This app deploys to ZevCloud, a Node.js server host. Set the Nitro/server preset to node-server (not cloudflare, vercel or netlify) in the framework config (vite.config.ts, app.config.ts or nuxt.config.ts, whichever this project uses), remove any Cloudflare Workers or Vercel adapter plugins, keep the build command `npm run build` and the start command `node .output/server/index.mjs`, and make sure the server listens on the PORT environment variable on all interfaces. Then run the build and confirm .output/nitro.json says "preset": "node-server".
> ```

## Related

- [Troubleshooting: app stops right after starting](/guide/troubleshooting#app-stops-right-after-starting-with-no-error-in-the-logs)
- [Web Applications: build configuration](/guide/web-apps#build-configuration)
- [Crash-loop protection](/guide/web-apps#crash-loop-protection)
