# How Toft reads your repository

> The ordered checks that pick your app's framework, and what to do when the pick is wrong.

Source: /toft-docs/latest/user/build/how-detection-works/

You don't declare a framework. Toft inspects the repository root — or the
**Folder** you set for a monorepo — and the first check that matches wins.

## The order

| # | Check | Framework |
|---|---|---|
| 1 | `[batch]` in `toft.toml` | A [batch app](/toft-docs/latest/user/automation/jobs.md): jobs only, no server |
| 2 | `[static]` in `toft.toml` | [Static site](/toft-docs/latest/user/build/static.md), overriding everything below |
| 3 | `next.config.js`/`.mjs`/`.ts`, or `next` in `package.json` | [Next.js](/toft-docs/latest/user/build/node.md) |
| 4 | `package.json` with a `start` script | [Node](/toft-docs/latest/user/build/node.md) |
| 5 | `go.mod` plus a `main` package | [Go](/toft-docs/latest/user/build/go.md) |
| 6 | One `.Rmd` or R-engine `.qmd` at the root | [R document](/toft-docs/latest/user/build/notebooks.md) |
| 7 | One `.ipynb` or Python `.qmd` at the root, or one marimo `.py` | [Notebook](/toft-docs/latest/user/build/notebooks.md) or [marimo](/toft-docs/latest/user/build/python.md) |
| 8 | `app.R`, `ui.R` + `server.R`, `plumber.R`, or an annotated `.R` | [Shiny or plumber](/toft-docs/latest/user/build/r.md) |
| 9 | `requirements.txt`, `pyproject.toml` or `Pipfile` | [Python](/toft-docs/latest/user/build/python.md) |
| 10 | A folder of HTML with none of the files above | [Static site](/toft-docs/latest/user/build/static.md) |

- **R wins over Python.** An `app.R` beside a `requirements.txt` is an R app.
- **A notebook wins over a Python server.** A Flask repo with an `.ipynb` at
  its root deploys as a notebook. Move the notebook into a subfolder.

## Several candidates are refused

When one shape has more than one candidate — two notebooks, two `.Rmd` files,
several HTML files and no `index.html` — the deploy fails and lists them. Name
the one you mean in [`toft.toml`](/toft-docs/latest/user/build/toft-toml.md).

## When it picks wrong

| Symptom | Fix |
|---|---|
| "Unsupported framework" on a front-end repo | There's no `start` script. Commit the build output and declare [`[static] root`](/toft-docs/latest/user/build/static.md). |
| Python repo refused with no entry point | Add one of `app.py`, `main.py`, `streamlit_app.py`, `server.py`, `wsgi.py` at the root. |
| Detected as a notebook, you wanted a server | Move the notebook out of the root. If viewers need to change inputs, use marimo, Streamlit or Shiny. |
| A `.qmd` detected as Python, you wanted R | Set its engine. See [Notebooks](/toft-docs/latest/user/build/notebooks.md). |

> **Tip**
>
> Every build log states the framework it detected and the language version it
> resolved. Read that line first, and again to confirm a fix took effect.
