Context
Devkit ships shared toolchain configs consumed by fleet repos via @gingur/devkit (github:gingur/devkit#main). We are moving to the Vite+ stack: oxlint (1.73.0, stable) replaces ESLint, oxfmt (0.58.0) replaces Prettier, TypeScript baseline moves to ^6 || ^7. Facts verified 2026-07-10: oxfmt passes 100% of Prettier's JS/TS conformance tests; md/yaml/html are formatted by a Prettier bundled inside oxfmt (no separate prettier dep needed); oxfmt defaults are printWidth 100, semi true, trailingComma "all" (singleQuote defaults false). typescript@7.0.2 ships a native tsc bin; nothing in this repo needs the TS JS compiler API once typescript-eslint is gone. oxlint config supports extends (paths resolved relative to the extending file). npx @oxlint/migrate (v1.73.0) generates .oxlintrc.json from an ESLint flat config. Docs: https://oxc.rs/docs/guide/usage/linter/config.md , https://oxc.rs/docs/guide/usage/formatter/config.md , https://oxc.rs/docs/guide/usage/formatter/migrate-from-prettier.md
Changes
configs/:
- Delete
eslint.config.mjs and prettier.config.mjs.
- Add
configs/oxlintrc.base.json: start from npx @oxlint/migrate run against the old configs/eslint.config.mjs (intent: js.configs.recommended + tseslint.configs.recommended), then hand-review. Keep the ignore patterns (dist/**, node_modules/**, coverage/**, .astro/**).
- Add shared oxfmt config carrying the old Prettier intent:
{ "printWidth": 100, "singleQuote": true, "semi": true, "trailingComma": "all", "sortPackageJson": false }. (sortPackageJson is ON by default in oxfmt — disable to avoid surprise churn; judgment call, revisit later.) Sharing mechanism: prefer a configs/oxfmt.config.mjs default-exporting the options object so consumers' oxfmt.config.ts can re-export it (mirrors the old prettier pattern); verify that works — fallback is consumers running oxfmt -c node_modules/@gingur/devkit/configs/.oxfmtrc.json. Document whichever mechanism survives verification in README.
configs/lint-staged.config.js: '*.{js,mjs,cjs,ts,tsx,jsx}' → ['oxfmt', 'oxlint --fix']; '*.{json,md,yml,yaml,css}' → ['oxfmt'].
configs/tsconfig.base.json: verify all 9 flags under TS7 tsc (remove/adjust anything rejected or deprecated).
package.json:
exports: remove ./eslint, ./prettier; add ./oxlint → ./configs/oxlintrc.base.json and ./oxfmt → the oxfmt config file. Keep ./tsconfig, ./lint-staged, ./infisical-scan.
peerDependencies: remove eslint, @eslint/js, prettier, typescript-eslint; add oxlint: ^1, oxfmt: ^0.58; typescript → ^6 || ^7.
devDependencies: mirror (drop the four; add oxlint ^1.73, oxfmt pinned 0.58.x, typescript ^7). Refresh pnpm-lock.yaml.
README.md (~lines 43–59 consumer-config section, line 59 install one-liner, pre-commit section):
- Update the exports/peer table and install command (
pnpm add -D oxlint oxfmt typescript).
- Consumer examples:
.oxlintrc.json with { "extends": ["./node_modules/@gingur/devkit/configs/oxlintrc.base.json"] }; oxfmt wiring per the verified mechanism; scripts "lint": "oxlint", "fmt": "oxfmt", "fmt:check": "oxfmt --check".
- Migration note: consumers move in lockstep (devkit consumed via
#main); TS7 for consumers without a TS-JS-API dependency, TS6 where one remains (e.g. @astrojs/check peers ^5 || ^6).
Rule mapping deliverable (no silent drops)
The PR description MUST include a mapping table: every rule enabled by js.configs.recommended and tseslint.configs.recommended → the oxlint rule that covers it, or an explicit "no oxlint equivalent" row with disposition (accepted-drop rationale). Generate from @oxlint/migrate output + the oxlint rules reference; review by hand.
Verification (evidence required in the PR)
pnpm install clean (no peer warnings).
- Sample
.ts file: pnpm exec oxlint -c configs/oxlintrc.base.json <sample> runs and flags a seeded violation (e.g. unused var).
- Prettier-parity spot check: format a representative sample (ts + json + md) with old prettier config vs
oxfmt; diff for ts/json is empty (md may differ slightly — report the diff).
tsc --noEmit (TS7) passes in a temp project extending configs/tsconfig.base.json; include tsc --showConfig.
- lint-staged config resolves: stage a misformatted file, run
npx lint-staged, file gets formatted+linted.
Acceptance criteria
- Old eslint/prettier config files deleted; oxlint/oxfmt configs exported; peers/devDeps as specified; lockfile updated; README updated; mapping table in PR; all five verification outputs cited.
Context
Devkit ships shared toolchain configs consumed by fleet repos via
@gingur/devkit(github:gingur/devkit#main). We are moving to the Vite+ stack: oxlint (1.73.0, stable) replaces ESLint, oxfmt (0.58.0) replaces Prettier, TypeScript baseline moves to^6 || ^7. Facts verified 2026-07-10: oxfmt passes 100% of Prettier's JS/TS conformance tests; md/yaml/html are formatted by a Prettier bundled inside oxfmt (no separateprettierdep needed); oxfmt defaults are printWidth 100, semi true, trailingComma "all" (singleQuote defaults false). typescript@7.0.2 ships a nativetscbin; nothing in this repo needs the TS JS compiler API once typescript-eslint is gone. oxlint config supportsextends(paths resolved relative to the extending file).npx @oxlint/migrate(v1.73.0) generates.oxlintrc.jsonfrom an ESLint flat config. Docs: https://oxc.rs/docs/guide/usage/linter/config.md , https://oxc.rs/docs/guide/usage/formatter/config.md , https://oxc.rs/docs/guide/usage/formatter/migrate-from-prettier.mdChanges
configs/:eslint.config.mjsandprettier.config.mjs.configs/oxlintrc.base.json: start fromnpx @oxlint/migraterun against the oldconfigs/eslint.config.mjs(intent:js.configs.recommended+tseslint.configs.recommended), then hand-review. Keep the ignore patterns (dist/**,node_modules/**,coverage/**,.astro/**).{ "printWidth": 100, "singleQuote": true, "semi": true, "trailingComma": "all", "sortPackageJson": false }. (sortPackageJsonis ON by default in oxfmt — disable to avoid surprise churn; judgment call, revisit later.) Sharing mechanism: prefer aconfigs/oxfmt.config.mjsdefault-exporting the options object so consumers'oxfmt.config.tscan re-export it (mirrors the old prettier pattern); verify that works — fallback is consumers runningoxfmt -c node_modules/@gingur/devkit/configs/.oxfmtrc.json. Document whichever mechanism survives verification in README.configs/lint-staged.config.js:'*.{js,mjs,cjs,ts,tsx,jsx}'→['oxfmt', 'oxlint --fix'];'*.{json,md,yml,yaml,css}'→['oxfmt'].configs/tsconfig.base.json: verify all 9 flags under TS7tsc(remove/adjust anything rejected or deprecated).package.json:exports: remove./eslint,./prettier; add./oxlint→./configs/oxlintrc.base.jsonand./oxfmt→ the oxfmt config file. Keep./tsconfig,./lint-staged,./infisical-scan.peerDependencies: removeeslint,@eslint/js,prettier,typescript-eslint; addoxlint: ^1,oxfmt: ^0.58;typescript→^6 || ^7.devDependencies: mirror (drop the four; addoxlint ^1.73,oxfmtpinned0.58.x,typescript ^7). Refreshpnpm-lock.yaml.README.md(~lines 43–59 consumer-config section, line 59 install one-liner, pre-commit section):pnpm add -D oxlint oxfmt typescript)..oxlintrc.jsonwith{ "extends": ["./node_modules/@gingur/devkit/configs/oxlintrc.base.json"] }; oxfmt wiring per the verified mechanism; scripts"lint": "oxlint","fmt": "oxfmt","fmt:check": "oxfmt --check".#main); TS7 for consumers without a TS-JS-API dependency, TS6 where one remains (e.g.@astrojs/checkpeers^5 || ^6).Rule mapping deliverable (no silent drops)
The PR description MUST include a mapping table: every rule enabled by
js.configs.recommendedandtseslint.configs.recommended→ the oxlint rule that covers it, or an explicit "no oxlint equivalent" row with disposition (accepted-drop rationale). Generate from@oxlint/migrateoutput + the oxlint rules reference; review by hand.Verification (evidence required in the PR)
pnpm installclean (no peer warnings)..tsfile:pnpm exec oxlint -c configs/oxlintrc.base.json <sample>runs and flags a seeded violation (e.g. unused var).oxfmt; diff for ts/json is empty (md may differ slightly — report the diff).tsc --noEmit(TS7) passes in a temp project extendingconfigs/tsconfig.base.json; includetsc --showConfig.npx lint-staged, file gets formatted+linted.Acceptance criteria