# TanStack Start

> A TanStack Start or TanStack Router app is edited like any Vite + React project, and midcode reads its file routes as pages.

- Page: https://midcode.app/docs/frameworks/tanstack-start
- From the midcode docs. Every page as Markdown: https://midcode.app/llms.txt
- Status: This ships with the next release of midcode. The version you can download today (1.1.2) doesn't have it yet.

midcode treats a TanStack Start app as what it is: a Vite project written in React. It's started, marked and edited exactly as described in [React with Vite](https://midcode.app/docs/frameworks/react-vite.md). What this page adds is the one thing specific to TanStack: its routes are files, so midcode can list them as pages.

The same goes for a plain Vite app that uses TanStack Router with file routes.

## At a glance

| | TanStack Start |
| --- | --- |
| Detected by | `vite` and `react` in `package.json`. The routes are found by the folder that holds `__root.tsx` |
| Runs with | `vite dev`, with a config of midcode's that loads yours and adds one plugin |
| Elements are marked by | That plugin, as Vite transforms each `.tsx` and `.jsx` file |
| Editing | Full, in `.tsx` and `.jsx` files |
| Components | Yes: instances, props, variants and states, variables |
| Pages | The route files of `src/routes`. New pages and removing them |
| Styles | Tailwind 4 classes, or `mid:` classes with `midcode.css` |

## How midcode runs it

There is no check for TanStack itself. midcode sees `vite` in `package.json`, with `react`, and starts Vite with its own config in front of yours:

```bash
vite dev /Users/you/apps/start-app \
  --config "/Users/you/Library/Application Support/midcode/injected/vite.config.mjs" \
  --port 4310 --strictPort --host localhost
```

That config loads your `vite.config`, with its `tanstackStart()` plugin and everything else, and adds the plugin that marks each JSX element with its file, line and column. Nothing is written in your project. Options in your `dev` script, such as `--mode`, are kept. The port in it isn't: midcode picks its own. The details, and what happens when Vite doesn't start this way, are in [React with Vite](https://midcode.app/docs/frameworks/react-vite.md).

A route file is marked like any other component:

```tsx title="src/routes/index.tsx"
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/')({ component: Home })

function Home() {
  return (
    <main className="p-8">
      <h1 className="text-4xl font-bold">Welcome</h1>
    </main>
  )
}
```

```html
<h1 data-mc="src/routes/index.tsx:8:7" class="text-4xl font-bold">Welcome</h1>
```

## Pages

midcode looks for `__root.tsx` (or `.jsx`, `.ts`, `.js`) in `src/routes`, `app/routes` and `src/app/routes`. The folder that has it is the routes folder, and each `.tsx` or `.jsx` file in it or in its subfolders is a page. The address comes from the file's name, read the way TanStack Router reads it:

| File | Page |
| --- | --- |
| `index.tsx` | `/` |
| `about.tsx` | `/about` |
| `posts.index.tsx` or `posts/index.tsx` | `/posts` |
| `posts.$postId.tsx` | `/posts/[postId]`, a dynamic route |
| `posts_.$postId.edit.tsx` | `/posts/[postId]/edit` |
| `_app.settings.tsx` | `/settings` |
| `(marketing)/pricing.tsx` | `/pricing` |
| `files.$.tsx` | `/files/[...]` |

Dots nest like folders. Parts that only group or wrap add nothing to the address: a name that starts with `_`, a `(group)` folder, `route.tsx`, `.lazy`. Not listed: `__root`, anything whose name starts with `-`, and an `api` folder at the top.

A dynamic route is one entry. midcode finds its pages in the running site, from its sitemap and the links on its pages. See [Pages and navigation](https://midcode.app/docs/editor/pages.md).

"New page" in the page menu writes a route file with its `createFileRoute`, and "Remove" moves a route's file to the Trash:

```tsx title="src/routes/about.tsx"
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/about')({ component: About })

function About() {
  return (
    <main className="mx-auto max-w-3xl px-6 py-24">
      <h1 className="text-4xl font-semibold">About</h1>
      <p className="mt-4">A new page, made in midcode.</p>
    </main>
  )
}
```

A deeper path uses dots: `/posts/first` is `posts.first.tsx`. The class names are written when Tailwind is in your `package.json`. Both are offered when `__root.tsx` (or `.jsx`) is in `src/routes`, or `__root.tsx` in `app/routes`.

## Styles

With Tailwind 4, midcode writes Tailwind's classes: see [Tailwind CSS](https://midcode.app/docs/styling/tailwind.md).

Without it, midcode writes `mid:` utilities and compiles them to `midcode.css`. It imports that file in the module `index.html` loads, or in `src/main.*`, `src/index.*` or `src/entry-client.*`. A TanStack Start app usually has none of those. In that case midcode writes `src/midcode.css` and tells you it couldn't tell where to import it: load it in `src/routes/__root.tsx`, the way your app loads its other stylesheet. See [Without Tailwind](https://midcode.app/docs/styling/without-tailwind.md).

## Limits

- Only the file names are read. Routes built in code, virtual file routes and a custom routes folder set in the plugin's options aren't followed. Any page can still be opened by typing its path in the page menu.
- An older TanStack Start project that has no `vite` in its `package.json` isn't recognised as a Vite project: it runs with its own `dev` script and shows without marks.
- No free canvas: it's for Next.js projects on the App Router.
- [Site settings](https://midcode.app/docs/editor/site-settings.md) writes the `<head>` of an `index.html` at the project's root. A Vite app that uses TanStack Router has one. A TanStack Start app usually doesn't (its `<head>` is built in its root route), and then the globe isn't in the top bar: set the title and the rest in code.
- No TanStack Start version is on record as tried end to end. The route reader follows TanStack Router's file naming, and everything else is the Vite + React path, which is tried.
- The other limits of [React with Vite](https://midcode.app/docs/frameworks/react-vite.md) apply.
