A linter runs beside the language’s own server and adds its diagnostics and quick fixes to the same file. TypeScript reports type errors and ESLint reports its rules, both underlined in the one editor, both in the Problems panel.
Settings > Linters has a card for each, with its status and an on or off switch.
The four linters
| Linter | Languages | Runs when the project has | Comes from |
|---|---|---|---|
| ESLint | TypeScript, JavaScript | eslint.config.* or .eslintrc* |
Server bundled with Tori, rules from the project’s eslint |
| Biome | TypeScript, JavaScript, JSON, CSS, GraphQL | biome.json or biome.jsonc |
The project’s own biome |
| oxlint | TypeScript, JavaScript | .oxlintrc.json, .oxlintrc.jsonc or oxlint.config.ts |
The project’s own oxlint |
| Ruff | Python | ruff.toml, .ruff.toml, or [tool.ruff] in pyproject.toml |
The project’s own ruff, else the one on your PATH |
A linter only starts where its config file sits between the file and the project root, so a repo without one never runs it. Creating or deleting the config while Tori is open switches the linter on or off for the open files with no restart. Several can run on one file: a repo with both an ESLint and a Biome config gets both.
Setting one up
Install the linter in the project, the way the project already pins its tools, and add its config file:
# ESLintnpm install --save-dev eslintnpm init @eslint/config@latest
# Biomenpm install --save-dev --save-exact @biomejs/biomenpx @biomejs/biome init
# oxlintnpm install --save-dev oxlint
# Ruff, in the project's virtualenvpip install ruffUse pnpm add -D, yarn add -D, bun add -d or uv add --dev if that is
what the project uses. Tori finds the binary in the nearest
node_modules/.bin, .venv/bin or venv/bin, so the version you see in the
editor is the one CI runs. Run your install before opening the file; a
linter whose config exists but whose binary does not shows as not found on
its card.
Every linter runs code from the project (plugins, configs written in JavaScript), so it only starts in a trusted project.
Fixing on save
Fix all on save, in Settings > Editor, applies every fix the linters offer before the file is
formatted and written. Individual fixes are on the lightbulb in the gutter,
or Opt+Enter on the diagnostic.
Turning one off
Use the card’s switch, or list it in lsp.disabled. A project can turn a
linter off for everyone who opens it, in .tori/settings.json:
{ "lsp": { "disabled": ["oxlint"] } }Adding a linter
A linter is a language server with role = "secondary", so any linter that
speaks LSP can be added as a TOML file in ~/.config/tori/packs/lsp/, or
from the catalog with Add a linter. This one is the shape of
the built in oxlint, under its own id, since a file may not reuse a built in
one:
schema_version = 1id = "oxlint-mine"label = "oxlint (mine)"role = "secondary"root_markers = [".git"]activation_markers = [".oxlintrc.json", ".oxlintrc.jsonc"]
[languages]ts = "typescript"tsx = "typescriptreact"js = "javascript"jsx = "javascriptreact"
[launch]kind = "project_bin"program = "oxlint"args = ["--lsp"]activation_markers is what keeps it to projects that use it; leave it out
and it runs on every matching file. project_bin looks in the project’s
node_modules/.bin and virtualenv first, then your PATH. Restart Tori after
adding the file. A linter with no LSP mode cannot be added this way yet.
Missing a linter?
Request a linter. Say which tool, the config file that marks a project as using it, and whether it has an LSP mode.