tanstack-start-project-setup

$npx mdskill add netlify/swar-templates/tanstack-start-project-setup

Use the existing starter's package.json, vite.config.ts, tsconfig.json, and netlify.toml as the source of truth. These projects use Vite and the Start Vite plugin, not Vinxi, app.config.ts, or a server preset. Do not replace the project's framework or assume scripts that are not defined.

SKILL.md

.github/skills/tanstack-start-project-setupView on GitHub ↗
---
name: tanstack-start-project-setup
description: Set up and configure TanStack Start projects. Use when creating new projects, configuring the router, setting up TanStack Query integration, or configuring build settings.
license: Apache-2.0
metadata:
  author: tanstack
  version: "1.0"
---

# TanStack Start project setup

Use the existing starter's package.json, vite.config.ts, tsconfig.json, and netlify.toml as the source of truth. These projects use Vite and the Start Vite plugin, not Vinxi, app.config.ts, or a server preset. Do not replace the project's framework or assume scripts that are not defined.

## Build configuration

This complete Vite configuration works with the Vite 7 and 8 versions used by the starters. It uses Vite's standard alias option. Basic already uses Vite 8's native resolve.tsconfigPaths; retain that option there. Older starters use vite-tsconfig-paths; keep it unless replacing it with an equivalent supported alias configuration.

```ts file=vite.config.ts
import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vite'
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import netlify from '@netlify/vite-plugin-tanstack-start'

export default defineConfig({
  resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } },
  plugins: [tailwindcss(), netlify(), tanstackStart(), react()],
})
```

Start must precede the React plugin. Put Content Collections before Start when the project uses that optional integration. The Netlify adapter generates the server entry; don't configure a separate .output/server functions directory.

## Router and server errors

Create a router per request. Register its type so links and route parameters can be checked. Set the default error component on the router, not only the root route: child-route SSR failures select a route-local error component or the router default. Keep internal error details off the page.

```tsx file=src/router.tsx
import { createRouter, useRouter, type ErrorComponentProps } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'

function SafeErrorPage({ reset }: ErrorComponentProps) {
  const router = useRouter()
  return (
    <main>
      <h1>This page couldn’t load</h1>
      <p role="alert">Please try again or return home.</p>
      <button onClick={() => { void router.invalidate(); reset() }}>Try again</button>
      <a href="/">Go home</a>
    </main>
  )
}

export function getRouter() {
  return createRouter({
    routeTree,
    scrollRestoration: true,
    defaultPreloadStaleTime: 0,
    defaultErrorComponent: SafeErrorPage,
  })
}

declare module '@tanstack/react-router' {
  interface Register { router: ReturnType<typeof getRouter> }
}
```

Retain an existing branded safe error component when one is supplied. src/routeTree.gen.ts is generated by dev/build and should not be edited. Root document and route examples are in the tanstack-start-routes skill.

## TypeScript and commands

Keep strict mode, ES2022, Bundler resolution, react-jsx, noEmit, and the @/* source alias. Keep verbatimModuleSyntax disabled for Start's server/client transforms. Build/dev must run once before tsc so route and optional content types exist. Generated content imports also require the path mapping described in the content-collections skill.

Check that React Router and Start resolve the same @tanstack/router-core version. Separate core versions can prevent Start's API-route type extensions from reaching React Router, causing TypeScript to reject the server option even when a Vite build succeeds.

Use Node 22.13+ on the Node 22 line, Node 24, or Node 26+ across this repository. Start requires at least 22.12; the newer lint/test tooling raises the Node 22 floor to 22.13. Check installed engines and peer dependencies during upgrades. Keep exact package versions and remove unused/duplicate entries when updating a starter.

Every starter defines npm run dev and npm run build. Only use npm run typecheck, lint, test, preview, or format when package.json defines them; otherwise the installed tools can be called with npx --no-install tsc --noEmit or npx --no-install vite preview. A Vite build alone does not type-check.

The Netlify build configuration is:

```toml
[build]
  command = "vite build"
  publish = "dist/client"
[dev]
  command = "npm run dev"
  targetPort = 3000
  port = 8888
```

Keep credentials in server functions/server handlers, not VITE_* variables, route-loader results, or browser modules. Loaders also run during client navigation. Use the relevant Netlify data/auth skill when adding those features; no database or authentication is part of project setup by default.

TanStack Query is optional. If needed, install compatible query and router SSR integration packages, create QueryClient inside getRouter(), declare root context, and wire provider plus dehydration/hydration together. A provider alone does not implement SSR cache transfer. Follow the installed integration's documentation rather than adding a module-level user-data cache.

Reference: https://tanstack.com/start/latest/docs/framework/react/build-from-scratch

More from netlify/swar-templates

SkillDescription
content-collectionsUse content-collections for type-safe content management with markdown files. Use when building blogs, documentation sites, or any content-driven pages with frontmatter and markdown.
netlify-forms-tanstackHandle Netlify Forms in TanStack Start. Use when implementing contact forms, signup forms, or any form submission handling on Netlify-hosted TanStack Start sites.
netlify-identity-tanstack-startUpgrade a stock TanStack Start project to use Netlify Identity for authentication via the @netlify/identity package. Use this skill whenever the user wants to add Netlify Identity auth to a TanStack Start app, integrate login/signup into TanStack Start, protect routes or server functions with Netlify Identity, add role-based access control, or wire up Netlify Identity webhooks. Also use when the user mentions '@netlify/identity', 'nf_jwt', or asks about auth for TanStack Start on Netlify. Covers SSR pages, SPA pages, API routes, server functions, middleware, route guards, role-based access, identity webhooks, and client-side auth state.
tanstack-start-api-routesCreate API routes (server routes) in TanStack Start for handling HTTP requests. Use when building REST APIs, webhooks, or any HTTP endpoint that returns data rather than rendering a page.
tanstack-start-loadersLoad data for TanStack Start routes using beforeLoad and loader functions. Use when fetching data for pages, implementing route guards, or setting up route context. IMPORTANT - Loaders should call server functions for data access.
tanstack-start-routesCreate and manage routes in TanStack Start using file-based routing. Use when adding new pages, configuring layouts, setting up nested routes, or working with route parameters.
tanstack-start-server-functionsCreate validated TanStack Start server functions and composable middleware for server-only logic called from loaders or components.
tanstack-start-typesafe-routingImplement type-safe navigation and links in TanStack Start. Use when creating links, navigating programmatically, working with search params, or accessing route parameters with full TypeScript support.