# Ultracite > Ultracite is the linter and formatter for agentic development. A zero-config preset for Oxlint, Biome, and ESLint that keeps agent-written code consistent and type-safe. # ultracite@5.6.0 Source: https://www.ultracite.ai/changelog/ultracite-5-6-0 ## Minor Changes - 762ef70: Workflow improvements ## Patch Changes - f3ec41b: Backport changelog --- # ultracite@5.6.1 Source: https://www.ultracite.ai/changelog/ultracite-5-6-1 ## Patch Changes - 44917fd: Fix package readme, move vitest to devDeps ## Minor Changes - 762ef70: Workflow improvements ## Patch Changes - f3ec41b: Backport changelog --- # ultracite@5.6.2 Source: https://www.ultracite.ai/changelog/ultracite-5-6-2 ## Patch Changes - 7b515fe: Disable useAwait rule in next config files - 7b515fe: Improve test coverage - c3a9dad: Bump deps - 3faa8c2: Add Roo Code editor rules support --- # ultracite@5.6.3 Source: https://www.ultracite.ai/changelog/ultracite-5-6-3 ## Patch Changes - a167b1c: Update Biome to 2.2.6 --- # ultracite@5.6.4 Source: https://www.ultracite.ai/changelog/ultracite-5-6-4 ## Patch Changes - 679719b: Temporarily disable Qwik rules --- # ultracite@6.0.0 Source: https://www.ultracite.ai/changelog/ultracite-6-0-0 ## Major Changes - 86ee61e: Add specific Ultracite configurations ## Minor Changes - d704b5c: Add first-class support for Astro ## Patch Changes - c5c7ca1: Disable project rules - ff83b52: Compress Ultracite agent rules - 8987c58: Upgrade to Biome 2.3.0 - acd8c42: Brand and docs update - ed1bcb6: Docs updates and bump deps - d0ba90b: Tie framework selection to agent context --- # ultracite@6.0.1 Source: https://www.ultracite.ai/changelog/ultracite-6-0-1 ## Patch Changes - 5848800: Fix legacy ultracite config --- # ultracite@6.0.2 Source: https://www.ultracite.ai/changelog/ultracite-6-0-2 ## Patch Changes - 9566f79: Upgrade to Biome 2.3.1 --- # ultracite@6.0.3 Source: https://www.ultracite.ai/changelog/ultracite-6-0-3 ## Patch Changes - 82e5353: Drop legacy ultracite preset --- # ultracite@6.0.4 Source: https://www.ultracite.ai/changelog/ultracite-6-0-4 ## Patch Changes - b0a7281: setting cursor rule context to glob pattern instead of always apply --- # ultracite@6.0.5 Source: https://www.ultracite.ai/changelog/ultracite-6-0-5 ## Patch Changes - 5f00bd3: Use overrides in presets - 30f488e: Upgrade Biome to 2.3.2, add "noIncrementDecrement" --- # ultracite@6.1.0 Source: https://www.ultracite.ai/changelog/ultracite-6-1-0 ## Minor Changes - b6bdc8e: Introduce Warp agentic terminal support ## Patch Changes - ba72503: Fix husky initialization - b038a60: Fix overrides in Astro, Svelte, Vue presets having no effect - b7451ee: Improve core glob - f7ebeb8: Improve test coverage for agents --- # ultracite@6.2.0 Source: https://www.ultracite.ai/changelog/ultracite-6-2-0 ## Minor Changes - 4035389: add cursor hooks functionality - 18ed1f3: Refactor rules based on hooks and feedback from Cursor team ## Patch Changes - 7aa5fd8: pass diagnostic-level filter option (stop-gap) - f9e2141: Update existing tsconfig files instead of creating a new root one --- # ultracite@6.2.1 Source: https://www.ultracite.ai/changelog/ultracite-6-2-1 ## Patch Changes - 527e737: Update to Biome 2.3.3 - d5f9d64: Disable useAwait on page.tsx and layout.tsx files in Next.js - eb77e3f: add allowForLoopAfterthoughts to noIncrementDecrement --- # ultracite@6.3.0 Source: https://www.ultracite.ai/changelog/ultracite-6-3-0 ## Minor Changes - a5a1510: Add new hooks flag, add Claude hooks support ## Patch Changes - 0fed52b: Upgrade Biome to 2.3.4 - a9347c8: Disable noMagicNumbers and noConsole - aa7f769: Updated tsconfig, package.json selector --- # ultracite@6.3.1 Source: https://www.ultracite.ai/changelog/ultracite-6-3-1 ## Patch Changes - 908ac57: Add missing hooks cli definition --- # ultracite@6.3.10 Source: https://www.ultracite.ai/changelog/ultracite-6-3-10 ## Patch Changes - bc7d89f: Fix nested next.config.ts detection - d292922: Replace hardcoded npx commands --- # ultracite@6.3.12 Source: https://www.ultracite.ai/changelog/ultracite-6-3-12 ## Patch Changes - 635acd1: Fix "canceled" bug for realsies this time --- # ultracite@6.3.2 Source: https://www.ultracite.ai/changelog/ultracite-6-3-2 ## Patch Changes - 7537f01: Improve CI support --- # ultracite@6.3.3 Source: https://www.ultracite.ai/changelog/ultracite-6-3-3 ## Patch Changes - 9132af5: Upgrade to Biome 2.3.5 --- # ultracite@6.3.4 Source: https://www.ultracite.ai/changelog/ultracite-6-3-4 ## Patch Changes - 3edc530: Bump glob to resolve dependency vulnerability - 30ac12c: Update Biome to 2.3.6 --- # ultracite@6.3.5 Source: https://www.ultracite.ai/changelog/ultracite-6-3-5 ## Patch Changes - 1bccc30: Upgrade Biome to 2.3.7 - 3837d19: Fix Zed config - 06a8871: Use force-ignore pattern --- # ultracite@6.3.6 Source: https://www.ultracite.ai/changelog/ultracite-6-3-6 ## Patch Changes - 99a417c: Fix docs on quotes - 5fb7031: Add support for max diagnostics flag - c66c232: Remove process.exit from CLI --- # ultracite@6.3.7 Source: https://www.ultracite.ai/changelog/ultracite-6-3-7 ## Patch Changes - fec49ac: added cloudflare wrangler generated file to the ignore list --- # ultracite@6.3.8 Source: https://www.ultracite.ai/changelog/ultracite-6-3-8 ## Patch Changes - e5e48db: Bump Biome to 2.3.8 - 0a525d9: Update docs --- # ultracite@6.3.9 Source: https://www.ultracite.ai/changelog/ultracite-6-3-9 ## Patch Changes - a13eb72: Add support for Factory Droid AI assistant --- # ultracite@6.4.0 Source: https://www.ultracite.ai/changelog/ultracite-6-4-0 ## Minor Changes - 6201822: Add custom reporter --- # ultracite@6.4.1 Source: https://www.ultracite.ai/changelog/ultracite-6-4-1 ## Patch Changes - a8570b3: respect package manager in generated rules and commands --- # ultracite@6.4.2 Source: https://www.ultracite.ai/changelog/ultracite-6-4-2 ## Patch Changes - 42fc700: Disable scanner rules - aff09df: Fix plugin install logging - 0f57252: Upgrade to Biome 2.3.9 - c15b770: Fix reporter - 99dda79: Fix extension install logging - d759789: Bump Biome to 2.3.10 --- # ultracite@6.4.3 Source: https://www.ultracite.ai/changelog/ultracite-6-4-3 ## Patch Changes - 393a0d1: Explicitly enable css - 127c1c6: Fix reporter bug for --unsafe flag - 41a73ba: Fix file-based metadata - 43b07be: Fix tsconfig patching - 9d1d374: Add support for pre-commit (python) - f9256db: Add support for Antigravity --- # ultracite@6.5.0 Source: https://www.ultracite.ai/changelog/ultracite-6-5-0 ## Minor Changes - 628a5c3: Disable nursery rules ## Patch Changes - a942392: Use `interface` as consistent type definition --- # ultracite@7.0.0 Source: https://www.ultracite.ai/changelog/ultracite-7-0-0 ## Major Changes - c4a205f: Remove i18n docs - c4a205f: Remove custom reporter - c4a205f: Scaffold support for ESLint and Oxlint - c4a205f: Add support for Amazon Q, Crush, Firebender, OpenCode, Qwen and Trae - c4a205f: Move biome config under `biome` ## Patch Changes - 5538022: Increase max allowed complexity - 5508d47: Remove GraphQL override that disables formatter/linter - e1b6be6: Fix undefined input to fix command - 618ae17: Fix changesets - Updated dependencies [c4a205f] - @repo/data@2.0.0 --- # ultracite@7.0.1 Source: https://www.ultracite.ai/changelog/ultracite-7-0-1 ## Patch Changes - a8408b6: Fix bundling issues --- # ultracite@7.0.10 Source: https://www.ultracite.ai/changelog/ultracite-7-0-10 ## Patch Changes - a7b34ed: Add Vercel Agent support - b6658ce: Add Claude Code hook integration to run `ultracite fix` after `Write`/`Edit` tool usage. --- # ultracite@7.0.11 Source: https://www.ultracite.ai/changelog/ultracite-7-0-11 ## Patch Changes - 79d2756: fix: exit with code 1 when check/fix finds errors - c032612: Fix: Parser Errors on .jsonc Files Due to Comments - a556651: Move oxlint to optionalDependencies or peerDependencies --- # ultracite@7.0.12 Source: https://www.ultracite.ai/changelog/ultracite-7-0-12 ## Patch Changes - f328fc6: Update nypm to remove dependency on corepack - 6f638fa: Fix error message when exiting with code 1 - f328fc6: Fix eslint dependencies during initialization - f328fc6: Allow comments in json files --- # ultracite@7.0.2 Source: https://www.ultracite.ai/changelog/ultracite-7-0-2 ## Patch Changes - 246c1fc: Update docs and README Remove catalog dependencies --- # ultracite@7.0.3 Source: https://www.ultracite.ai/changelog/ultracite-7-0-3 ## Patch Changes - 92eaa89: Cleanup dist files --- # ultracite@7.0.4 Source: https://www.ultracite.ai/changelog/ultracite-7-0-4 ## Patch Changes - 7e9b76c: Fix legacy imports --- # ultracite@7.0.5 Source: https://www.ultracite.ai/changelog/ultracite-7-0-5 ## Patch Changes - ab47642: add --type-aware and --type-check flags for oxlint --- # ultracite@7.0.6 Source: https://www.ultracite.ai/changelog/ultracite-7-0-6 ## Patch Changes - 702f6b5: Upgrade Biome to 2.3.11 --- # ultracite@7.0.7 Source: https://www.ultracite.ai/changelog/ultracite-7-0-7 ## Patch Changes - ea7a6dc: Fix oxlint import path - a6e43a0: Add more CLI options for oxlint, oxfmt and biome - ad52a16: Fix linter provider mention in agent rules --- # ultracite@7.0.8 Source: https://www.ultracite.ai/changelog/ultracite-7-0-8 ## Patch Changes - a9efe80: Add Cursor CLI as agent - 00fb477: Add support for Mistral Vibe --- # ultracite@7.0.9 Source: https://www.ultracite.ai/changelog/ultracite-7-0-9 ## Patch Changes - 95dd898: Disable sort-imports in favor of oxfmt - c72d2b3: Disable react/jsx-max-depth - 2ae8976: Disable typescript/require-await --- # ultracite@7.1.1 Source: https://www.ultracite.ai/changelog/ultracite-7-1-1 ## Patch Changes - 0e9af01: Automatically add scripts to root package.json - 656f6d7: fix(oxlint-remix): ignore unicorn rules for generated routeTree.gen.ts --- # ultracite@7.1.2 Source: https://www.ultracite.ai/changelog/ultracite-7-1-2 ## Patch Changes - 9d443b6: Fix func-style config in oxlint - 3d9b488: Fix: argument --unsafe cannot be used multiple times in this context - f06808f: Don't pass options to formatters, only linters --- # ultracite@7.1.3 Source: https://www.ultracite.ai/changelog/ultracite-7-1-3 ## Patch Changes - c60533d: Fix oxlint import/consistent-type-specifier-style --- # ultracite@7.1.4 Source: https://www.ultracite.ai/changelog/ultracite-7-1-4 ## Patch Changes - 34c79bb: Fix conflicting oxlint rules --- # ultracite@7.1.5 Source: https://www.ultracite.ai/changelog/ultracite-7-1-5 ## Patch Changes - c8fdacf: fix: detectLinter() doesn't walk up directory tree, Breaks monorepo subdirectory usage - c79c3b0: Fix lefthook file configuration - 4b9d206: Make useBlockStatements fix safe - 8e9e728: Add support for NestJS - d0ae8f3: Fix: Biome removes all imports in Svelte files on save instead of organizing them --- # ultracite@7.10.0 Source: https://www.ultracite.ai/changelog/ultracite-7-10-0 ## Minor Changes - cd0a36c: Add `--claude` and `--codex` flags to `ultracite fix`. After the normal autofix pass, remaining diagnostics are handed to the Claude Code or Codex CLI non-interactively, one agent run per affected file, with a live per-issue spinner that flips to ✓/✗ once the fix is verified by a re-lint. Fixes that don't survive verification are retried (up to 3 attempts per file) with the fresh diagnostics and feedback that the previous approach failed. Works with all three linter modes (Oxlint, Biome, ESLint); exits non-zero if any issues remain, matching the plain `fix` contract. - e089510: Scope React Doctor's framework-specific rules to per-framework add-on presets (#752) The `ultracite/oxlint/js-plugins` preset no longer enables React Doctor's `nextjs-*` and TanStack (`query-*`, `tanstack-start-*`) rules for every consumer. Rules like `nextjs-no-img-element` and `tanstack-start-no-anchor-element` fire on plain ``/`` JSX and recommend framework replacements, which falsely errored in Vite + React and other non-Next/non-TanStack projects. Those rules now live in two new add-on presets: - `ultracite/oxlint/next/js-plugins` - `ultracite/oxlint/tanstack/js-plugins` `ultracite init` wires the matching add-on automatically when you select the framework together with `oxlint-plugin-react-doctor`. If you manage `oxlint.config.ts` by hand and use Next.js or TanStack, add the matching add-on preset to `extends` alongside `js-plugins` to keep those rules — or re-run `npx ultracite init`. Also fixes re-running `init` on a config that already extends `js-plugins` producing a duplicate `import jsPlugins` declaration. ## Patch Changes - 3320cd8: Update Biome to 2.5.6. No stable (non-nursery) rules were added, removed, or promoted between 2.5.3 and 2.5.6, so the preset configs are unchanged. - 477cd6e: Update ESLint to 10.8.0 and all ESLint plugins to their latest versions. Highlights: - `eslint-plugin-react-doctor` 0.9.3: the react preset expands from 149 to 417 rules, adopting the upstream `recommended` set (react-router, three.js/r3f, ink, motion, remotion, zustand/valtio/mobx, and more) while excluding rules that duplicate already-enabled `react`, `react-hooks`, and `jsx-a11y` rules. The next preset gains `nextjs-async-dynamic-api-not-awaited` and `nextjs-metadata-url-consistency`; the tanstack preset gains `tanstack-start-missing-scripts`, `query-floating-mutate-async`, and `query-no-mutation-in-effect-as-read`. - `eslint-plugin-unicorn` 72: adds `no-missing-local-resource`, `no-multiple-promise-resolver-calls`, `no-shorthand-property-overrides`, `no-transition-all`, `no-unnecessary-string-trim`, `no-useless-re-export`, `prefer-then-catch`, and `require-frontmatter-fields`. CSS-only rules are excluded from the preset since they fail config validation for JS files. - `eslint-plugin-sonarjs` 4.2: adds 11 rules including `no-fixed-wait-in-tests`, `parameterized-tests`, `assertions-in-test-cases`, `prefer-native-lodash-alternative`, and `explicit-test-skip`. - `typescript-eslint` 8.65: `@typescript-eslint/no-loop-func` and `@typescript-eslint/no-restricted-imports` were deprecated upstream in favor of the base rules, which now apply to TypeScript files. - `eslint-plugin-astro` 3: removes `astro/no-omitted-end-tags` and `astro/valid-compile`. - `eslint-plugin-svelte` 3.22: adds `no-bind-value-on-checkable-inputs` and `no-conflicting-module-names`; `no-restricted-html-elements` is now off because its schema requires a user-supplied element list. - `@angular-eslint/eslint-plugin` 22.1: adds `inject-at-top` and `prefer-service-decorator`. - b81578b: Fix the useSortedPackageJson action not being executed by turning on assist actions for package.json-like files. - 9ec454a: Update oxlint to 1.76.0 and oxfmt to 0.61.0. New stable rules added to the presets: `oxc/bad-match-all-arg`, `id-denylist`, `node/exports-style` (core), `react/function-component-definition` with arrow-function components (react), and `vitest/padding-around-test-blocks` (vitest). `node/no-top-level-await` is off — top-level await is idiomatic in ESM, Astro frontmatter, and build scripts — and the ESLint preset's `n/no-top-level-await` is now off to match. No rules were removed or promoted out of nursery. - ba61c02: Fix generated oxlint.config.ts accessing plugin.name on ExternalPluginEntry without narrowing the string form, which caused a TypeScript error in projects that type-check the config (#753) --- # ultracite@7.10.1 Source: https://www.ultracite.ai/changelog/ultracite-7-10-1 ## Patch Changes - d018b7f: Fix several agent fix mode (`fix --claude`/`--codex`) issues: runs no longer abort with ENOBUFS when linter JSON output exceeds 1MB, user-supplied format/reporter flags can no longer override the JSON reporter and break parsing, a stuck agent process is force-killed 10 seconds after the timeout instead of hanging forever, and the progress renderer no longer garbles TTY output when file paths and rule names exceed the terminal width. - d018b7f: Fix Biome config migration leaving the legacy bare `"extends": ["ultracite"]` form in place, which breaks Biome's module resolution since the package has no root export. It's now mapped to `ultracite/biome/core`. - d018b7f: Fix `ultracite doctor` reporting spurious failures: config checks now walk up parent directories (matching `check`/`fix` and the linters themselves) so monorepo packages inheriting a root config pass, `.oxlintrc.json` is accepted as a valid oxlint config (with a migration suggestion), and Prettier/Stylelint configs declared via `package.json` keys are recognized. - d018b7f: Fix `ultracite init` corrupting existing Prettier/Stylelint/ESLint configs by writing an ESM module into JSON/YAML/TOML/CJS config files (e.g. `.prettierrc`, `eslint.config.cjs`). Updates now write the default `.mjs` config instead and remove the incompatible file so it can't shadow the new one. - d018b7f: Fix `ultracite check`/`fix` misrouting space-separated flag values (e.g. `--max-warnings 10`) into the file list, which scrambled the underlying linter invocation and made formatters fail on bogus targets. Positional files listed before a `--` separator are also kept as lint targets instead of being reclassified as passthrough, which could silently widen formatter runs to the whole project. - d018b7f: Fix Lefthook and pre-commit YAML updates silently doing nothing on common config shapes: the Lefthook job is now inserted correctly when `jobs:` isn't the first key under `pre-commit:` (and no longer matches a `jobs:` key in a different hook), `repos: []` in `.pre-commit-config.yaml` is handled, and shapes that can't be safely edited produce a warning instead of writing the file back unchanged. - d018b7f: Fix the Husky integration overwriting an existing `.husky/pre-commit` hook: `ultracite init` ran `husky init`, which unconditionally replaces the hook with `npm test`. It now runs plain `husky` to set up the hooks infrastructure without touching the hook file. - d018b7f: Fix `ultracite init` destroying user files it couldn't parse or merge: unparseable `tsconfig.json` files are no longer replaced with a minimal config, unparseable `.vscode`/`.zed` settings are no longer overwritten wholesale, and lint-staged configs with function-valued entries are left untouched — all now warn and skip instead. - d018b7f: Fix re-running `ultracite init` on an oxlint setup silently enabling the full js-plugins preset — the previously selected JS plugins are now preserved when no new selection is made. Init also no longer flips an explicit `"type": "commonjs"` in package.json to `"module"`; it warns instead. - d018b7f: Fix switching linters removing `storybook` from the project's dependencies. It was swept into the removal set as a peer of `eslint-plugin-storybook`, but it's a user-facing tool a project may use independently of linting. - d018b7f: Fix Stylelint target generation dropping directories with a dot in their name (e.g. `app.web`) and producing non-matching globs from Windows-style backslash paths. Framework detection also handles negated workspace patterns (`!packages/legacy`) again. - d018b7f: Fix the CLI becoming a silent no-op (exiting 0 without linting anything) when a generic `TEST` environment variable is set, as is common in CI matrices. The internal test guard now uses `ULTRACITE_TEST`. - 36c7b80: Move @typescript-eslint/utils from dependencies to devDependencies. It was accidentally shipped as a runtime dependency in 7.9.0, pulling eslint and the typescript-eslint packages into every consumer's install (including oxlint-only setups) via npm's automatic peer dependency installation. Nothing in the published package imports it — it only exists to support the workspace-internal rule-parity script. --- # ultracite@7.10.2 Source: https://www.ultracite.ai/changelog/ultracite-7-10-2 ## Patch Changes - 1c48c68: Enable Tailwind CSS class sorting (`sortTailwindcss`) in the Oxfmt preset. Classes in `class`/`className` attributes and in `clsx`, `cva`, `tw`, `twMerge`, `cn`, `twJoin`, and `tv` calls are now sorted using the same algorithm as `prettier-plugin-tailwindcss`, matching the behavior of the Prettier preset (which always loads the Tailwind plugin) and the Biome preset's `useSortedClasses` rule. Projects without Tailwind installed are unaffected beyond class strings being sorted against the default theme, and oxfmt versions older than 0.35.0 ignore the option. - dc78be4: Stop sorting TanStack route option keys in route files. TanStack Router's route option types are order-sensitive (`head`/`component` infer `loaderData` from properties declared before them), so the Biome `useSortedKeys` source action rewrote `createFileRoute` literals into an order that breaks type inference (`loaderData` becomes `never`). The Biome TanStack preset now disables `useSortedKeys` for route files, and the oxlint TanStack preset disables `sort-keys` there so route files aren't caught between it and `react-doctor/tanstack-start-route-property-order`. --- # ultracite@7.10.3 Source: https://www.ultracite.ai/changelog/ultracite-7-10-3 ## Patch Changes - a1fa9c4: Replace the hand-rolled package `exports` map matching in the config-resolution doctor check with the resolve.exports library, which implements Node's full `PACKAGE_TARGET_RESOLVE` algorithm (wildcard patterns, key-order precedence, conditional exports, and array fallbacks). The manual `node_modules` walk is kept intentionally — it exists to avoid Bun's auto-install cache resolving specifiers the project's own `node_modules` can't. - 414ea80: Replace the hand-rolled monorepo workspace scan in framework detection with the find-workspaces library. Workspace declarations from package.json (array and yarn-classic object form) and pnpm-workspace.yaml — including negated globs — are now resolved by the library instead of manual pattern collection and globbing, and lerna/bolt monorepos are picked up as well. - a9a1989: Replace the hand-rolled upward directory walks in `findNearestFile` and `detectLinter` with the empathic library's `find.any`, which checks candidate names in order within each directory before moving to the parent — the same per-directory precedence the previous implementation enforced manually. - 27b2707: Use magicast to update ESM lint-staged config files during `ultracite init`. The config is now edited as an AST instead of being imported and re-serialized, so comments and function-valued entries elsewhere in the config survive the update, and the user's config code is no longer executed. If the Ultracite glob pattern is already owned by a non-array value, or the config isn't a mergeable object literal (e.g. `defineConfig(...)`), init warns and leaves the file untouched instead of rewriting it. CommonJS configs keep the previous behavior. - f2529b8: Rewrite the agent-fix progress renderer on top of log-update, cli-truncate, and string-width. log-update now owns the in-place block rewriting that was previously done with manual cursor-up/clear-line escape sequences, and line truncation is measured by display width instead of code units — so lint messages containing emoji or CJK text can no longer overflow the terminal row and corrupt the animated block. - 277b9d6: Replace the hand-rolled child-process handling in the agent fix runner with execa. The timeout → SIGTERM → grace period → SIGKILL escalation, stderr capture, and spawn-failure handling now use execa's `timeout` and `forceKillAfterDelay` options, which are battle-tested across platforms (including Windows kill semantics the manual implementation didn't cover). Behavior is unchanged: agent runs still time out after 5 minutes, escalate to SIGKILL after a 10-second grace period, and report a capped stderr tail. - 1614a80: Drop the direct cross-spawn dependency: all synchronous process spawning (linter runs, tool version checks, editor extension installs, skill installs) now goes through a small adapter over execa's sync API, which owns the Windows spawn semantics cross-spawn provided. The adapter preserves the spawnSync result shape (`status`/`signal`/`error`/`stdout`), always disables shell interpretation, and always decodes output as UTF-8. execa was already a dependency for the agent fix runner, so this consolidates on one process-spawning library. - ac114b4: Replace the glob dependency with fast-glob for the tsconfig.json scan during init. fast-glob was already in the dependency tree via find-workspaces, so this drops glob's transitive dependencies (minipass, path-scurry, etc.) from the install without changing behavior. --- # ultracite@7.10.4 Source: https://www.ultracite.ai/changelog/ultracite-7-10-4 ## Patch Changes - 417a85a: Add an opt-in `ultracite/oxlint/anti-slop` preset that ships a vendored, self-contained build of the [anti-slop](https://github.com/dmmulroy/anti-slop) Oxlint plugin — fifteen rules that reject low-evidence TypeScript and JavaScript patterns (unjustified type assertions, `unknown` leaking through signatures, `Reflect`-based access, module mocking, and more). Extend it alongside `ultracite/oxlint/core`; nothing extra to install. The preset also turns off two core rules that conflict with anti-slop's widening checks (`typescript/consistent-indexed-object-style` and `unicorn/no-immediate-mutation`) when extended after core. - 4d3fab8: Move `suspicious/useArraySortCompare` from the Biome core config to the opt-in type-aware config. The rule is in Biome's `types` domain — it type-infers the receiver of every method call before checking the method name, which made `ultracite check` up to ~260x slower on projects with expensive library types (zod, better-auth, Prisma). It now only runs when type-aware linting is explicitly enabled, alongside the other type/project-domain rules. Fixes #768. --- # ultracite@7.10.5 Source: https://www.ultracite.ai/changelog/ultracite-7-10-5 ## Patch Changes - 8df6ad0: Offer the vendored `anti-slop` Oxlint preset during `ultracite init` — it now appears in the JS-plugins prompt when you pick Oxlint, and non-interactive setup accepts it via `--js-plugins anti-slop`. Selecting it adds `ultracite/oxlint/anti-slop` to the generated config's `extends`; since the preset is vendored inside Ultracite, nothing extra is installed. - cd229e9: Bump the `oxlint-plugin-react-doctor` pin from `^0.7.1` to `^0.9.12`, so `ultracite init` installs the current plugin. All react-doctor rules enabled by the js-plugins presets still exist in 0.9.12, and the ported rules run in curated mode via the settings shipped alongside this release (#771). - e1ac886: Pin React Doctor's ported rules to their framework-aware "curated" mode (#771). react-doctor 0.9.x rewrote its ported oxc/react-refresh rules — notably `only-export-components` — with a stripped-down default mode: no framework detection, no route-file skipping, and `allowConstantExport` off, so Next.js route-segment exports like `export const dynamic = "force-static"` or `metadata` were flagged as non-component exports in every route file. The ESLint react preset now sets `settings["react-doctor"].portedRuleMode: "curated"`, and generated oxlint configs apply a new `jsPluginSettings` export from `ultracite/oxlint/js-plugins` on the root config (oxlint does not merge `settings` from extended configs, so the setting cannot ride along inside the preset). If you extend the js-plugins preset manually, add `settings: jsPluginSettings` to your root oxlint config. - c27fe36: Generate oxlint configs that enable a subset of the JS plugins via a new `selectJsPlugins` export from `ultracite/oxlint/js-plugins`, instead of inlining the filtering logic into the generated file. The inlined block contained a `typeof` check that user-side lint presets flagged (`anti-slop/no-runtime-typeof`, #770); the generated config is now a one-line extend, is emitted already formatted (including the previously missing blank line after imports), and re-running `ultracite init` migrates existing configs with the old inlined block automatically. - 0616523: Update the vendored `anti-slop` Oxlint plugin to upstream commit `446268e`, picking up fixes to `no-object-parameters` and `no-unknown-returns` (respect lexical type binders in alias resolution) and a new `allowInTypeGuards` option on `no-runtime-typeof`. The `ultracite/oxlint/anti-slop` preset enables `allowInTypeGuards`, so `typeof` checks inside type predicate functions (`(x): x is T`) no longer need disable comments — predicates are the named-boundary pattern the rule pushes toward (dmmulroy/anti-slop#10). --- # ultracite@7.10.6 Source: https://www.ultracite.ai/changelog/ultracite-7-10-6 ## Patch Changes - 972b946: Update the oxlint presets for oxlint 1.79: replace the removed `react/react-compiler` rule with the 22 new React Compiler rules in the react preset, add `jsdoc/no-blank-blocks` and `one-var` to the core preset (mirrored in the ESLint presets), and require oxlint ^1.79.0 - 2d5bbdb: Declare the `jsPluginSettings` named export in the `ultracite/oxlint/js-plugins` type declarations, so the documented (and `ultracite init`-generated) `import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins"` type-checks (#773) - 56aef65: Refresh the toolchain versions that `ultracite init` installs into projects: `@biomejs/biome` 2.5.9, the ESLint plugin family (including eslint-plugin-cypress 7, eslint-plugin-jsdoc 64, eslint-plugin-solid 0.15, and eslint-plugin-unicorn 73 — the dynamic presets adopt their new rules automatically), and `prettier-plugin-svelte` 4.1.1 / `prettier-plugin-tailwindcss` 0.8.1 --- # ultracite@7.10.7 Source: https://www.ultracite.ai/changelog/ultracite-7-10-7 ## Patch Changes - 15f7ae0: Add support for the Aube package manager: `ultracite init --pm aube` is now accepted and projects with an `aube-lock.yaml` lockfile are detected automatically - 1afc8fe: Re-declare selected Oxlint JS plugins on the root config so dependency analyzers see them. `ultracite init --linter oxlint --js-plugins ...` now generates `const jsPlugins = selectJsPlugins([...])` and adds `jsPlugins: jsPlugins.jsPlugins` to the root config (also when the full `ultracite/oxlint/js-plugins` preset is extended). Knip only resolves `jsPlugins` from the root Oxlint config and never walks `extends`, so `eslint-plugin-github`, `eslint-plugin-sonarjs`, and `oxlint-plugin-react-doctor` were reported as unused devDependencies. Oxlint dedupes the plugin between the root and the extended preset, so linting is unchanged. Also fix `ultracite update` dropping the `js-plugins` preset from `extends` when the config used the documented `import jsPlugins, { jsPluginSettings } from "ultracite/oxlint/js-plugins"` form: the import parser only matched bare default imports. The regenerated full-preset config keeps `settings: jsPluginSettings` on the root as well. - 20b06bf: Ignore `.alchemy` across all linters and formatters. Alchemy (alchemy.run) writes local state and generated bindings to a `.alchemy` directory. It is now part of the shared ignore patterns synced into Biome's `files.includes` and imported by oxlint, oxfmt, and ESLint, and the Stylelint preset ignores it via `ignoreFiles`. Prettier needs no change: it already respects `.gitignore`/`.prettierignore`. - 6e9286c: Run `lefthook install` during `ultracite init` through the same spawn adapter as every other tool invocation instead of `execSync`, so it no longer goes through a shell and gets the same Windows command resolution as `husky`, the linters, and editor extension installs. - 8b24f34: Add support for the Nub package manager: `ultracite init --pm nub` is now accepted and projects with a `nub.lock` lockfile are detected automatically (requires nypm ^0.6.9) - 240cb6b: Install into the workspace root correctly for Nub and Aube monorepos: nypm emits no root selector for them, so `nub add` ran without `-w` and was refused. Ultracite now hands nypm pnpm's flag set for these pnpm-compatible CLIs, producing `nub add --workspace-root --save-dev ultracite` - 44ecbba: Add Vitest type-test files (`**/*.{test-d,spec-d}.{ts,tsx,js,jsx}`) to the test-file globs so the shared test relaxations and the Vitest rule overrides apply to them, and enable the Vitest plugin's `typecheck` setting in the ESLint preset so `expectTypeOf`/`assertType` count as assertions. - 7ba6bb8: Package the reusable Ultracite agent skill with the npm distribution. --- # ultracite@7.10.8 Source: https://www.ultracite.ai/changelog/ultracite-7-10-8 ## Patch Changes - 2a43fdd: Turn off `unicorn/prefer-reflect-apply` in the `ultracite/oxlint/anti-slop` preset. When extended after `ultracite/oxlint/core`, the core rule recommended rewriting `Function#apply()` to `Reflect.apply()`, which anti-slop's `no-reflect-apply` then rejected, leaving no way to satisfy both. Direct-call guidance for `.apply()` still comes from `eslint/prefer-spread` and `eslint/no-useless-call`. - 03196df: Update `@biomejs/biome` to 2.5.12. Releases 2.5.10 through 2.5.12 only add nursery rules, which the Biome presets exclude, so the presets are unchanged. The releases also carry linter and formatter fixes, including fewer `noUnusedVariables` false positives on merged interfaces, namespaces, and overload type parameters, an unsafe-by-default fix for `noThisInStatic`, and a large batch of Astro expression parsing fixes. - 031b867: Update oxfmt to 0.66.0. The 0.65 and 0.66 releases are formatter fixes only, mainly around comment placement between a statement head and its body, suppressed statements (decorators, typecast parens, semicolons), custom side-effect groups in `sortImports`, CommonMark list interruption in JSDoc, and trailing whitespace in YAML block scalars. The `:::` container-directive fence patch is re-targeted to the new markdown bundle; the patched code itself is unchanged. - 54affee: Update oxlint to 1.81.0. The 1.80 and 1.81 releases add no rules and remove none, so the presets are unchanged and the peer range stays at ^1.79.0. Notable fixes carried in: `no-use-before-define` now runs on JS and JSX files, `object-shorthand` preserves `__proto__` semantics, `unicorn/prefer-math-min-max` no longer applies an unsafe autofix, and JS plugin diagnostics with invalid or reversed locations are clamped instead of crashing. - 0b058d1: Fix `ultracite fix --codex` failing on recent Codex CLI releases. The Codex adapter invoked `codex exec --full-auto`, a flag Codex has since removed, so every attempt failed at argument parsing. It now runs `codex exec --sandbox workspace-write`, the equivalent non-interactive, workspace-scoped mode, which is also accepted by older Codex versions. Resolves #794. - e2346bb: Update the ESLint family to latest: eslint 10.9.1, typescript-eslint 8.69.0, eslint-plugin-unicorn 74, eslint-plugin-solid 0.17, eslint-plugin-jsdoc 64.3.5, eslint-plugin-react-doctor and oxlint-plugin-react-doctor 0.9.13, globals 17.12, and the angular, nestjs-typed, next, tanstack-query, cypress, html, jest and storybook plugins. The dynamic presets pick up the new rules automatically: the solid preset gains the eleven rules added in eslint-plugin-solid 0.16 and 0.17 (`removed-api`, `no-single-arg-create-effect`, `no-accessor-as-prop`, `valid-use-server`, `require-async-server-function`, `no-invalid-server-capture`, `no-browser-globals-in-server-function`, `no-module-scope-reactive-primitive`, `no-restated-default-options`, `prefer-onSettled-for-side-effects`, `prefer-structured-class`), which only report Solid 2.0 issues when `settings.solid.version` is set to 2 and stay silent on Solid 1.x code; the nestjs preset gains `forward-ref-injection-should-use-wrapper-type`, `swagger-file-upload-should-be-documented` and `uploaded-file-should-be-validated`. The curated jsdoc and react-doctor lists are unchanged. No enabled rule was removed or deprecated, and the ESLint/oxlint parity check still passes. - 7b0456e: `ultracite fix` now runs lint fixes before the formatter: oxlint before oxfmt, and ESLint then Stylelint before Prettier. A fixer can insert unformatted code, such as the braces `curly` adds, the imports `consistent-type-specifier-style` splits, or the font names Stylelint requotes, and running the formatter first left that code unformatted until the next run. Fixer-inserted code is now formatted in the same run. The `--claude` and `--codex` agent passes follow the same order. `unicorn/no-nested-ternary` is now off in the oxlint and ESLint presets: its fixer adds parentheses that oxfmt and Prettier remove, so the two tools rewrote the file on every run. The core `no-nested-ternary` rule still reports nested ternaries. - 8ddc078: Enable three rules added in Stylelint 17 in the Stylelint preset: `selector-no-deprecated` and `selector-no-invalid` report selectors that CSS has dropped or that cannot parse, and `relative-selector-nesting-notation` is set to `explicit`, so nested relative selectors are written `& > b` rather than `> b`. The `property-layout-mappings`, `unit-layout-mappings` and `value-keyword-layout-mappings` rules are deliberately left off, since they reject every physical property, unit and keyword and can only autofix with a per-project `languageOptions.directionality` setting. The repo's own Stylelint lock is refreshed from 16.26.1 to 17.14.1, which the config packages already required; `ultracite init` already installs `stylelint@latest` so users are unaffected by the lock change. - 4609d79: Update the vendored `anti-slop` Oxlint plugin to upstream v0.1.2 (commit `e8c4880`). The rule set is unchanged; this picks up a round of correctness fixes: `no-known-value-widening` now also reports known values passed into local `unknown`-typed type predicates, `no-object-parameters`, `no-unknown-parameters`, `no-unknown-returns` and `no-unknown-type-aliases` resolve scoped and transparent generic aliases (including block-scoped aliases and forward references), `no-unknown-returns` covers `PromiseLike`, `no-unsafe-dictionary-type` allows generic constraints such as `T extends Record`, `no-runtime-typeof` always allows existence probes against `"undefined"`, `no-shape-in-symbol-names` allows static member reads such as Zod's `schema.shape`, and `require-safety-comment-for-type-assertion` rejects empty justifications and gains a `markers` option (default `["SAFETY"]`). Upstream also added a separate opt-in `anti-slop-effect` plugin for Effect projects, which is not vendored. --- # ultracite@7.11.0 Source: https://www.ultracite.ai/changelog/ultracite-7-11-0 ## Minor Changes - d5d241f: Add `ultracite upgrade`, and make version drift between Ultracite and its linter visible instead of a crash. Bumping `ultracite` without bumping the linter fails on the next `check`/`fix` with Biome's `Found an unknown key` error (and the equivalent for ESLint and Oxlint), because each release enables rules from a specific linter version. - `ultracite upgrade` installs the latest `ultracite`, prints a release-notes link for the versions you crossed, then hands off to the freshly installed CLI to reinstall your toolchain at the versions that release was verified with: Biome; ESLint, Prettier, Stylelint and the plugins the preset imports; or Oxlint and Oxfmt. Optional extras already in your `package.json` (framework plugins, Oxlint JS plugins, `oxlint-tsgolint`) are bumped as well. Config files are never rewritten, and the run ends with the same diagnostics as `doctor`. - `ultracite doctor` now checks the installed Biome, ESLint, Prettier, Stylelint, Oxlint and Oxfmt versions against the range this release supports. Too old fails the check and points at `ultracite upgrade`; newer than the verified range only warns. - The supported ranges are declared as optional peer dependencies so package managers warn when they drift: `@biomejs/biome ^2.5.0`, `eslint ^10.0.0`, `prettier ^3.0.0`, `stylelint ^17.0.0`, `oxlint ^1.79.0`, `oxfmt >=0.40.0`. `ultracite init` now installs Prettier and Stylelint from those ranges instead of `latest`. Requires Biome >= 2.5.0, ESLint >= 10.0.0, Prettier >= 3.0.0, Stylelint >= 17.0.0, Oxlint >= 1.79.0 and Oxfmt >= 0.40.0. ## Patch Changes - 27d06f2: Update dependencies (`@clack/prompts`, `semver`, `zod`, ESLint plugins). - d322691: Default `ultracite init` to Oxlint + Oxfmt when `--linter` is omitted in quiet or non-interactive mode - c677cf5: Recommend Oxlint + Oxfmt in the `ultracite init` linter prompt and list it first - c5be848: Disable `no-use-before-define` in TanStack Router route files for the oxlint tanstack preset. File routes are mutually recursive (`Route` references the component, and the component calls `Route.useParams()`), so no declaration order could satisfy the rule. --- # ultracite@7.11.1 Source: https://www.ultracite.ai/changelog/ultracite-7-11-1 ## Patch Changes - 24b2797: Update oxfmt to 0.67.0 and re-target the markdown `:::` fence patch to the new dist chunk. The release changes no options; it fixes CSS/SCSS/Less comment preservation and a few JSDoc-cast edge cases in member chains. - 24b2797: Update oxlint to 1.82.0. The release adds and removes no rules, so the presets are unchanged apart from one new option: `no-unmodified-loop-condition` now runs with `checkConditionalExpressions: true` in the oxlint and ESLint core presets, so each branch of a ternary in a loop condition must be modified inside the loop rather than only the expression as a whole. - 24b2797: Update the ESLint family: `@angular-eslint/eslint-plugin` 22.5, `@typescript-eslint/*` 8.70, `eslint-plugin-solid` 0.18, `eslint-plugin-vue` 10.11, `eslint-plugin-jsdoc` 64.3.8, `eslint-plugin-cypress` 7.0.2, `@darraghor/eslint-plugin-nestjs-typed` 7.5.2 and `prettier-plugin-astro` 1.0. The dynamic presets pick up the seven new rules automatically: `@typescript-eslint/no-generated-empty-object-type`, `@angular-eslint/reactive-context-must-read-signal`, `vue/no-shadow-native-events`, and Solid's `no-boolean-enumerated-attribute`, `no-store-mutation-outside-setter`, `no-unused-signal` and `no-write-in-pure-computation`. Note that `prettier-plugin-astro` 1.0 is a rewrite on the Astro 7 Rust compiler (Node 22.12+); expect whitespace diffs on first run and mirror any custom `compressHTML` via its new `astroCompressHTML` option. - 24b2797: Refresh the stylelint lock to 17.15.0 and enable its new `selector-no-unmatchable` rule, which flags selectors that can never match (for example `label:checked`, `::before:first-child` or `:is(::before)`). - a71dda4: Stop sorting object keys across the whole TanStack presets, not just route files. TanStack Query mutation options are order-sensitive too: TypeScript infers the `onMutate` context from context-sensitive callbacks in source order, so moving `onError`/`onSettled` above `onMutate` turns the context into `{}` and `ultracite fix` broke type-correct code (`TS2339: Property '...' does not exist on type '{}'`). Mutation and query options live anywhere (hooks, components, colocated files), so the route-file exemption could not cover them. `ultracite/oxlint/tanstack` now sets `sort-keys` to `off` and `ultracite/biome/tanstack` now sets `useSortedKeys` to `off` for all files. - a9db61c: Disable `github/filenames-match-regex` for file-based route directories (`**/routes/**`) in the oxlint js-plugins preset, matching the existing `unicorn/filename-case` exemption in the TanStack preset. TanStack Router filenames such as `__root.tsx`, `$.tsx`, and `posts.$postId.tsx` no longer fail the GitHub filename rule. Resolves #799. --- # ultracite@7.12.0 Source: https://www.ultracite.ai/changelog/ultracite-7-12-0 ## Minor Changes - 1f427d7: Add an opt-in `ultracite/oxlint/shadcn` preset for [`@shadcn/lint`](https://github.com/shadcn-ui/lint), shadcn's agent-first linter for Tailwind v4 design systems. All six rules (`no-restyle`, `no-raw-colors`, `no-arbitrary-values`, `no-inline-styles`, `no-unknown-classes`, `require-static-classes`) run at `error` with the upstream `allow: ["layout"]` policy, and the component-authoring rules are relaxed inside `**/components/ui/**`. Enable it with `ultracite init --linter oxlint --js-plugins @shadcn/lint`, or extend it alongside `ultracite/oxlint/core` after installing `@shadcn/lint`. ## Patch Changes - 600e991: Accept file-based page route filenames in `github/filenames-match-regex`. Files under `pages/` (Astro, Next.js pages router) now match a bracket-aware pattern, so dynamic, rest and optional parameters such as `[slug].astro`, `[...slug].ts` and `[[...slug]].tsx` pass while non-route names like `BadPage.ts` are still rejected. - 66f97bb: Allow top-level `return` in Astro frontmatter. The core preset now turns off `unicorn/prefer-module` for `**/*.astro` files (the rule cannot be configured to allow only `return`), and keeps `require()`, `module.exports`, `__dirname` and `__filename` flagged there via `import/no-commonjs` and `no-restricted-globals`. --- # ultracite@7.12.1 Source: https://www.ultracite.ai/changelog/ultracite-7-12-1 ## Patch Changes - 00dd547: Agent hooks now fix only the file the agent edited. The generated hook command passes a new `--hook` flag, and `ultracite fix --hook` reads the agent's payload from stdin: Claude Code and CodeBuddy (`tool_input.file_path`), Cursor (`file_path`) and Windsurf (`tool_info.file_path`). A file outside the project, one that no longer exists, or one the project's linters do not handle is skipped. A payload with no readable file path keeps the previous whole-project run. Re-running `ultracite init` rewrites a hook from an earlier init to the new command, including one generated before this change or for a different package manager or linter. - 300a814: Update `@biomejs/biome` to 2.5.14. Releases 2.5.13 and 2.5.14 add only nursery rules (14 of them, including `noReturnInFinally`, `noSvelteAtHtmlTags` and `useValidTestTitle`), with no stable-group additions, removals or promotions. The Biome presets deliberately leave nursery rules off, so they are unchanged. - b8b183b: Update dependencies (`@clack/prompts` 1.8, `empathic` 2.1, `magicast`, `nypm`, `string-width` 8.3, `yaml` and `zod` 4.6). - b59b8aa: Update oxfmt to 0.70.0 and re-target the markdown `:::` fence patch. Releases 0.68 through 0.70 change no options; they fix suppression-comment handling, comment placement around operators and `as`/`satisfies`, and several YAML and CSS edge cases. oxfmt 0.69 also ships a native markdown formatter, but `.md` files still go through the Prettier-based path, so the fence patch still applies. - 548c8b0: Update oxlint to 1.85.0. Releases 1.83 through 1.85 add and remove no rules and change no options, so the presets are unchanged. Note that `jest/prefer-strict-equal`, `vitest/prefer-strict-equal`, `vitest/prefer-to-be-truthy` and `vitest/prefer-to-be-falsy` now offer suggestions instead of fixes, so `ultracite fix` reports them rather than rewriting them. `unicorn/consistent-function-scoping` also now catches functions that only capture variables from an outer ancestor scope. - 0bc6cd6: Update the ESLint family: `eslint` 10.11, `eslint-plugin-unicorn` 76, `@typescript-eslint/*` 8.70.1, `eslint-plugin-jsdoc` 64.5, `eslint-plugin-astro` 3.2, `eslint-plugin-n` 18.4, `eslint-plugin-vue` 10.11.1, `@tanstack/eslint-plugin-query` 5.104, `@next/eslint-plugin-next` 16.3.6, `@darraghor/eslint-plugin-nestjs-typed` 7.5.6, `eslint-plugin-qwik` 1.20.1, `eslint-plugin-html` 8.2.1 and `eslint-plugin-react-doctor` / `oxlint-plugin-react-doctor` 0.9.14. The ESLint core preset picks up unicorn's ten new JavaScript rules automatically: `no-async-iterator-callback`, `no-unused-builtin-method-return` (which replaces the now-deprecated `no-unused-array-method-return`), `no-unused-iterator-helper`, `no-useless-set-construction`, `no-using-resource-escape`, `prefer-combined-guards`, `prefer-iterator-zip`, `prefer-json-import`, `prefer-temporal-conversion` and `prefer-uint8array-hex`. The CSS-only unicorn rules added in v75 stay off for JavaScript files. unicorn 76 makes `no-immediate-mutation` skip conditional mutations and `no-break-in-nested-loop` skip `continue` by default; the preset keeps those defaults because oxlint's `no-immediate-mutation` behaves the same way and checking `continue` would contradict `prefer-continue`. - 0bcb2c6: Update `prettier-plugin-astro` to 1.1.0 (the version `ultracite init` installs for Astro projects with Prettier) and refresh the transitive Prettier lock to 3.9.9. Prettier 3.9.7 through 3.9.9 are formatting fixes with no option changes, so the Prettier preset is unchanged. prettier-plugin-astro 1.1 makes `astroAllowShorthand` tri-state. When it is unset, which is how Ultracite's generated config leaves it, attributes now stay as written instead of `{value}` being expanded to `value={value}`. Set `astroAllowShorthand: false` in your Prettier config to keep the 1.0 behaviour. - 8b39375: Update `@shadcn/lint` to 0.2.0 (the version `ultracite init` installs for the opt-in `ultracite/oxlint/shadcn` preset). The release adds Vue and Svelte support and fixes theme, barrel and class-site discovery; the rules and their options are unchanged, so the preset is too. Under Oxlint the plugin reads only the `