Lint with oxlint instead of ESLint

ESLint cannot parse this project's TypeScript: typescript@7 is the native port
with no JavaScript compiler API, which every ESLint TypeScript parser needs, and
typescript-eslint refuses to install with a >=4.8.4 <6.1.0 peer. oxlint parses
TypeScript without the compiler API, so it lints the .ts and the .js together in
about 20ms over the whole repo, and it runs the correctness category as errors.

It found one real thing on the first run: the drag harness built its fetch
options with a body key even for GET. The four opinionated rules it also flagged
are off with their reasoning in the README, since oxlint's config takes no
comments. lint is back in deploy.sh's checks, and the editor has lint tasks and
the oxc extension recommendation. Prettier is unchanged.
This commit is contained in:
tanshu committed 2026-09-22 23:21:19 +05:30
1 parent 75b6492493
commit 0667110886
8 files changed
+464 -20

No files matched your search

+22 -13
View File
@@ -82,26 +82,35 @@ npm run verify # integrity of .dev/data
npm run check-site -- http://127.0.0.1:3000 # checks a running site from outside
```
### Formatting
### Linting and formatting
```sh
npm run lint # oxlint
npm run lint:fix
npm run format # prettier --write
npm run format:check # what deploy.sh runs
```
Prettier owns formatting (`.prettierrc.json`); `docs/` is excluded because those
are hand-wrapped notes rather than code. `embeddedLanguageFormatting` is off on
purpose: the renderers build HTML inside `html` tagged template literals, and
letting Prettier reflow those would change the markup customers receive.
**oxlint** lints the TypeScript and the JavaScript together. This project's
`typescript@7` is the native port with no JavaScript compiler API, which every
ESLint TypeScript parser needs — `typescript-eslint` requires a
`>=4.8.4 <6.1.0` peer and refuses to install — and oxlint parses TypeScript
without one, so it is the linter that works here. It runs the correctness
category and takes about 20 ms over the whole repo. `.oxlintrc.json` turns four
opinionated rules off, and oxlint's config takes no comments, so the reasoning
lives here: `no-await-in-loop` because the loops that await are sequential on
purpose (one photo at a time, memory bounded); `unicorn/consistent-function-scoping`
because the helpers close over their route's dependencies; `unicorn/no-array-sort`
because `toSorted()` is worth adopting but that is a refactor rather than a bug;
and `oxc/no-map-spread` because clarity beats the micro-optimisation. Delete the
line to see what a rule would say. `npm run typecheck` remains the
deeper TypeScript gate (strict, with `noUnusedLocals`, `noUncheckedIndexedAccess`,
`exactOptionalPropertyTypes` and `erasableSyntaxOnly`).
**ESLint is deliberately absent.** This project's `typescript@7` is the native
port and ships no JavaScript compiler API, which every ESLint TypeScript parser
needs — `typescript-eslint` requires `typescript >=4.8.4 <6.1.0` and refuses to
install, and forcing it through leaves a parser that cannot read the compiler.
Linting only the JavaScript was not worth the config, so the TypeScript gate is
`npm run typecheck` (strict, with `noUnusedLocals`, `noUncheckedIndexedAccess`,
`exactOptionalPropertyTypes` and `erasableSyntaxOnly`) and ESLint can come back,
with `typescript-eslint`, once it supports TypeScript 7.
**Prettier** owns formatting (`.prettierrc.json`); `docs/` is excluded because
those are hand-wrapped notes rather than code. `embeddedLanguageFormatting` is
off on purpose: the renderers build HTML inside `html` tagged template literals,
and letting Prettier reflow those would change the markup customers receive.
Dragging Pages is the one interaction that only a browser can check, so there is
a harness for it. It needs `geckodriver` on PATH and a running dev server: