chore: migrate linting to Oxlint - #8057
Conversation
|
View your CI Pipeline Execution ↗ for commit dee31e5
☁️ Nx Cloud last updated this comment at |
🚀 Changeset Version Preview2 package(s) bumped directly, 6 bumped as dependents. 🟩 Patch bumps
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
📝 WalkthroughWalkthroughThe pull request replaces repository ESLint configuration with centralized Oxlint configuration, updates Nx and package lint commands, removes package-specific ESLint files, and renames suppression directives for Oxlint rule namespaces. ChangesOxlint migration
Estimated code review effort: 3 (Moderate) | ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bundle Size BenchmarksThis pull request does not affect bundle size in any measured scenario. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.oxlintrc.json:
- Line 26: Update the rules configuration in .oxlintrc.json to enable the curly
rule with error severity and the all option, enforcing braces for every control
statement.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 10c5c68f-23f9-4647-9af7-99b094a0286c
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (141)
.oxlintrc.jsonAGENTS.mdCONTRIBUTING.mde2e/e2e-utils/eslint.config.jse2e/e2e-utils/package.jsone2e/eslint-plugin-start/package.jsoneslint.config.jsnx.jsonpackage.jsonpackages/arktype-adapter/eslint.config.jspackages/arktype-adapter/package.jsonpackages/eslint-plugin-router/eslint.config.jspackages/eslint-plugin-router/package.jsonpackages/eslint-plugin-router/tsconfig.jsonpackages/eslint-plugin-start/eslint.config.jspackages/eslint-plugin-start/package.jsonpackages/eslint-plugin-start/src/rules/no-async-client-component/no-async-client-component.rule.tspackages/eslint-plugin-start/tsconfig.jsonpackages/history/eslint.config.jspackages/history/package.jsonpackages/nitro-v2-vite-plugin/eslint.config.jspackages/nitro-v2-vite-plugin/package.jsonpackages/react-router-devtools/eslint.config.jspackages/react-router-devtools/package.jsonpackages/react-router-ssr-query/eslint.config.jspackages/react-router-ssr-query/package.jsonpackages/react-router/eslint.config.tspackages/react-router/package.jsonpackages/react-router/src/Match.tsxpackages/react-router/src/Matches.tsxpackages/react-router/src/Scripts.tsxpackages/react-router/src/Transitioner.tsxpackages/react-router/src/fileRoute.tspackages/react-router/src/headContentUtils.tsxpackages/react-router/src/link.tsxpackages/react-router/src/not-found.tsxpackages/react-router/src/route.tsxpackages/react-router/src/useCanGoBack.tspackages/react-router/src/useLocation.tsxpackages/react-router/src/useMatch.tsxpackages/react-router/src/useRouterState.tsxpackages/react-router/tests/route.test-d.tsxpackages/react-router/tests/router.test-d.tsxpackages/react-router/tests/useBlocker.test-d.tsxpackages/react-router/tests/useLoaderData.test-d.tsxpackages/react-router/tests/useMatch.test-d.tsxpackages/react-router/tests/useParams.test-d.tsxpackages/react-router/tests/useRouteContext.test-d.tsxpackages/react-router/tests/useSearch.test-d.tsxpackages/react-start-client/eslint.config.jspackages/react-start-client/package.jsonpackages/react-start-client/src/GenericHydrate.tsxpackages/react-start-client/src/Hydrate.tsxpackages/react-start-client/src/hydration/never.tsxpackages/react-start-client/src/hydration/visible.tsxpackages/react-start-rsc/eslint.config.jspackages/react-start-rsc/package.jsonpackages/react-start-rsc/src/ReplayableStream.tspackages/react-start-rsc/src/createServerComponentFromStream.tspackages/react-start-server/eslint.config.jspackages/react-start-server/package.jsonpackages/react-start/eslint.config.jspackages/router-cli/eslint.config.jspackages/router-cli/package.jsonpackages/router-core/eslint.config.jspackages/router-core/package.jsonpackages/router-core/src/utils.tspackages/router-devtools-core/eslint.config.jspackages/router-devtools-core/package.jsonpackages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsxpackages/router-devtools-core/src/Explorer.tsxpackages/router-devtools-core/src/FloatingTanStackRouterDevtools.tsxpackages/router-devtools-core/src/useLocalStorage.tspackages/router-devtools-core/src/useMediaQuery.tspackages/router-devtools-core/src/utils.tsxpackages/router-devtools/eslint.config.jspackages/router-devtools/package.jsonpackages/router-generator/eslint.config.jspackages/router-generator/package.jsonpackages/router-generator/src/utils.tspackages/router-generator/tests/generator/types-disabled/routes/__root.tsxpackages/router-generator/tests/generator/types-disabled/routes/index.tsxpackages/router-generator/tests/generator/types-disabled/routes/posts.tsxpackages/router-generator/tests/generator/types-disabled/routes/posts/$postId.tsxpackages/router-generator/tests/generator/types-disabled/routes/users.$userId.tsxpackages/router-plugin/eslint.config.jspackages/router-plugin/package.jsonpackages/router-ssr-query-core/eslint.config.jspackages/router-ssr-query-core/package.jsonpackages/router-utils/eslint.config.jspackages/router-utils/package.jsonpackages/router-vite-plugin/eslint.config.jspackages/router-vite-plugin/package.jsonpackages/solid-router-devtools/eslint.config.jspackages/solid-router-devtools/package.jsonpackages/solid-router-ssr-query/eslint.config.jspackages/solid-router-ssr-query/package.jsonpackages/solid-router/eslint.config.tspackages/solid-router/package.jsonpackages/solid-router/src/fileRoute.tspackages/solid-start-client/eslint.config.jspackages/solid-start-client/package.jsonpackages/solid-start-client/src/GenericHydrate.tsxpackages/solid-start-server/eslint.config.jspackages/solid-start-server/package.jsonpackages/solid-start/eslint.config.jspackages/start-client-core/eslint.config.jspackages/start-client-core/package.jsonpackages/start-client-core/src/client-rpc/frame-decoder.tspackages/start-client-core/src/client-rpc/serverFnFetcher.tspackages/start-client-core/src/hydration/runtime.tspackages/start-fn-stubs/eslint.config.jspackages/start-fn-stubs/package.jsonpackages/start-plugin-core/eslint.config.jspackages/start-plugin-core/package.jsonpackages/start-plugin-core/src/start-compiler/compiler.tspackages/start-plugin-core/src/start-manifest-plugin/manifestBuilder.tspackages/start-server-core/eslint.config.jspackages/start-server-core/package.jsonpackages/start-static-server-functions/eslint.config.jspackages/start-static-server-functions/package.jsonpackages/start-storage-context/eslint.config.jspackages/start-storage-context/package.jsonpackages/valibot-adapter/eslint.config.jspackages/valibot-adapter/package.jsonpackages/virtual-file-routes/eslint.config.jspackages/virtual-file-routes/package.jsonpackages/vue-router-devtools/eslint.config.jspackages/vue-router-devtools/package.jsonpackages/vue-router-ssr-query/eslint.config.tspackages/vue-router-ssr-query/package.jsonpackages/vue-router/eslint.config.tspackages/vue-router/package.jsonpackages/vue-router/src/fileRoute.tspackages/vue-start-client/eslint.config.tspackages/vue-start-client/package.jsonpackages/vue-start-server/eslint.config.tspackages/vue-start-server/package.jsonpackages/vue-start/eslint.config.tspackages/zod-adapter/eslint.config.jspackages/zod-adapter/package.json
💤 Files with no reviewable changes (44)
- packages/solid-router-ssr-query/eslint.config.js
- packages/router-generator/eslint.config.js
- packages/vue-start/eslint.config.ts
- packages/router-core/eslint.config.js
- eslint.config.js
- packages/router-ssr-query-core/eslint.config.js
- packages/start-server-core/eslint.config.js
- packages/start-fn-stubs/eslint.config.js
- packages/zod-adapter/eslint.config.js
- packages/virtual-file-routes/eslint.config.js
- packages/react-router-devtools/eslint.config.js
- packages/history/eslint.config.js
- packages/start-client-core/eslint.config.js
- packages/router-devtools/eslint.config.js
- packages/eslint-plugin-router/eslint.config.js
- packages/router-devtools-core/eslint.config.js
- e2e/e2e-utils/eslint.config.js
- packages/react-start-rsc/eslint.config.js
- packages/arktype-adapter/eslint.config.js
- packages/router-utils/eslint.config.js
- packages/router-vite-plugin/eslint.config.js
- packages/start-storage-context/eslint.config.js
- packages/solid-start/eslint.config.js
- packages/solid-router-devtools/eslint.config.js
- packages/vue-router-ssr-query/eslint.config.ts
- packages/solid-router/eslint.config.ts
- packages/vue-start-server/eslint.config.ts
- packages/vue-start-client/eslint.config.ts
- packages/nitro-v2-vite-plugin/eslint.config.js
- packages/start-plugin-core/eslint.config.js
- packages/valibot-adapter/eslint.config.js
- packages/eslint-plugin-start/eslint.config.js
- packages/vue-router-devtools/eslint.config.js
- packages/start-static-server-functions/eslint.config.js
- packages/router-cli/eslint.config.js
- packages/react-router-ssr-query/eslint.config.js
- packages/vue-router/eslint.config.ts
- packages/solid-start-client/eslint.config.js
- packages/react-router/eslint.config.ts
- packages/router-plugin/eslint.config.js
- packages/react-start/eslint.config.js
- packages/react-start-client/eslint.config.js
- packages/solid-start-server/eslint.config.js
- packages/react-start-server/eslint.config.js
| "typeAware": true, | ||
| "respectEslintDisableDirectives": true | ||
| }, | ||
| "rules": { |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/sh
set -eu
printf '%s\n' '--- .oxlintrc.json ---'
cat -n .oxlintrc.json | sed -n '1,150p'
printf '%s\n' '--- repository references to curly and Oxlint configuration ---'
rg -n --hidden -g '!node_modules' -g '!dist' -g '!build' \
'"curly"|curly|oxlint|oxlintrc' . | sed -n '1,240p'
printf '%s\n' '--- local Oxlint metadata, if present ---'
find . -maxdepth 3 \( -iname '*oxlint*' -o -name 'package.json' \) -type f -print | sed -n '1,120p'Repository: TanStack/router
Length of output: 21764
🌐 Web query:
Oxlint curly rule support configuration schema
💡 Result:
In Oxlint, the curly rule is configured using an array format that accepts up to two elements, mirroring the traditional ESLint configuration style [1][2]. It does not support a single configuration object with named properties [3]. The configuration schema for the curly rule is as follows: 1. The first element (required) is the enforcement type, which must be one of: "all", "multi", "multi-line", or "multi-or-nest" [1][2]. 2. The second element (optional) accepts the string "consistent", which enforces consistent brace usage within if-else chains [1][2]. Example configurations in your.oxlintrc.json or oxlint.config.ts file: // Require braces for multi-statement blocks "rules": { "curly": ["error", "multi"] } // Require braces for multi-line blocks, with consistent usage in if-else chains "rules": { "curly": ["error", "multi-line", "consistent"] } Oxlint maintains its own rule implementations in Rust [4][5], and the curly rule's behavior and accepted configuration options are defined by the underlying native implementation, not by passing a configuration object [2][3]. If you encounter documentation or suggestions indicating that a configuration object (e.g., { "curlyType": "..." }) is supported, please note that this is incorrect and such configurations will not function as expected [3].
Citations:
- 1: https://oxc.rs/docs/guide/usage/linter/rules/eslint/curly
- 2: https://github.com/oxc-project/oxc/blob/7b80010b91591903b5f89a125193e2a6eda8e893/crates/oxc_linter/src/rules/eslint/curly.rs
- 3: linter: incorrect docs for eslint/curly oxc-project/oxc#18661
- 4: https://oxc.rs/docs/guide/usage/linter/rules.html
- 5: https://oxc.rs/blog/2026-03-11-oxlint-js-plugins-alpha.html
🏁 Script executed:
#!/bin/sh
set -eu
repo='oxc-project/oxc'
tag='oxlint_v1.78.0'
printf '%s\n' '--- exact-version curly rule source ---'
curl -fsSL "https://raw.githubusercontent.com/${repo}/${tag}/crates/oxc_linter/src/rules/eslint/curly.rs" \
| sed -n '1,240p'
printf '%s\n' '--- exact-version rule registration references ---'
curl -fsSL "https://api.github.com/repos/${repo}/git/trees/${tag}?recursive=1" \
| jq -r '.tree[]?.path' \
| rg 'curly|configuration_schema' \
| sed -n '1,120p'
printf '%s\n' '--- exact-version commit resolution ---'
curl -fsSL "https://api.github.com/repos/${repo}/git/ref/tags/${tag}" \
| jq '{ref, object}'Repository: TanStack/router
Length of output: 7918
🌐 Web query:
site:github.com/oxc-project/oxc "oxlint_v1.78.0" "curly"
💡 Result:
In oxlint, the curly rule corresponds to the standard ESLint rule of the same name, which enforces consistent use of curly braces for control statements [1][2]. As of oxlint v1.78.0, the rule configuration follows the ESLint-style format, using strings as arguments rather than an object-based configuration [3][4][5]. The rule supports the following configuration options: "all" (default): Requires curly braces for all control statements [1]. "multi": Requires curly braces only when the control statement block contains multiple lines [1]. "multi-line": Requires curly braces if the statement is multiline or if the body spans multiple lines [1]. "multi-or-nest": Requires curly braces for control statements that are multiline or nested [1]. Additionally, the "consistent" option can be added as a separate string argument to ensure consistency across statements (e.g., ["error", "multi-or-nest", "consistent"]) [4][5]. While there was previous confusion in the documentation regarding whether "consistent" should be an object property or a string argument, the project has clarified that it is implemented as a string argument to match ESLint's behavior [3][6][4]. If you are working with JSX, oxlint also provides the react/jsx-curly-brace-presence rule, which manages the presence of curly braces for JSX props and children [7].
Citations:
- 1: https://github.com/oxc-project/oxc/blob/7b80010b91591903b5f89a125193e2a6eda8e893/crates/oxc_linter/src/rules/eslint/curly.rs
- 2: feat(linter): add
curlyrule oxc-project/oxc#8123 - 3: linter: incorrect docs for eslint/curly oxc-project/oxc#18661
- 4: linter: "multi-or-nest", "consistent" conflicts oxc-project/oxc#18566
- 5: refactor(curly): enhance curly brace rule configuration and handling oxc-project/oxc#13498
- 6: docs(linter): Fix docs for the curly rule. oxc-project/oxc#18374
- 7: https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs
Enable the required curly rule.
Oxlint 1.78.0 supports this rule. Add "curly": ["error", "all"] to enforce braces for all control statements.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.oxlintrc.json at line 26, Update the rules configuration in .oxlintrc.json
to enable the curly rule with error severity and the all option, enforcing
braces for every control statement.
Source: Coding guidelines
Merging this PR will regress 9 benchmarks
|
Summary
test:eslinttotest:lintPerformance
Full uncached 40-project lint run, with task dependencies excluded for a like-for-like comparison:
Validation
test:linttargets pass with zero errorsgit diff --checkpassSummary by CodeRabbit
Chores
Documentation