# Ultracite: a zero-config preset for Biome, ESLint and Oxlint

> Ultracite is a CLI that wires hundreds of lint and format rules into an existing JavaScript or TypeScript project in one command. It is useful when nobody on the team wants to own a linter config, and awkward when you already have one you like.

**haydenbleasel/ultracite** — A highly opinionated, zero-configuration linter and formatter.

- Repository: https://github.com/haydenbleasel/ultracite
- Website: https://www.ultracite.ai/
- Stars: 3,300 · Forks: 126
- Language: TypeScript
- License: MIT
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/haydenbleasel-ultracite

## The problem Ultracite targets: lint config as an unpaid maintenance job

Every JavaScript or TypeScript repository eventually grows a lint configuration nobody wants to own. Someone adds a rule after a bad review. Someone else disables it six months later. The file survives the people who wrote it. Ultracite's answer is to delete that negotiation entirely: the README describes a preset of hundreds of rules tuned for modern JavaScript and TypeScript, applied by a single command. The intended user is a team that wants consistent formatting and type-safe code without spending review time on plugin versions, rule conflicts, or which of Biome, ESLint and Oxlint the project should standardise on. The README frames the audience broadly, covering single repos and monorepos, and it also targets a second consumer: AI coding agents. Ultracite generates ruleset and context files for Claude Code, GitHub Copilot, Cursor, Gemini and others, so a model editing your files follows the same style a human reviewer expects. That is the real pitch. Not better rules than you would write, but no rules for you to write.

## How the CLI, the presets and the linter toolchain fit together

Ultracite is a wrapper, not a linter. The repository is a Bun and Turborepo monorepo with apps/ and packages/ directories, and the published CLI lives under packages/cli. The CLI's job is to detect your package manager, ask which toolchain you want, then write config files and install the underlying binaries. Three toolchains are supported. Biome is described as all-in-one formatting and linting in a single binary. ESLint ships alongside Prettier and Stylelint for the largest plugin ecosystem. Oxlint and Oxfmt are Rust-based and, per the README, run dramatically faster than ESLint as part of the Oxc ecosystem. Ultracite also publishes the presets themselves, for Biome, ESLint, Oxlint, Oxfmt, Prettier and Stylelint, so you can extend them by hand instead of letting the CLI write your config. The data flow at runtime is short: ultracite check and ultracite fix resolve the configured linter and hand your files to it, passing through any flags they do not recognise. That pass-through matters, because it means Ultracite does not need to reimplement every linter option. The monorepo's own package.json shows the same tooling applied to itself, with oxfmt and oxlint pinned as devDependencies and a patchedDependencies entry for oxfmt, which is a reminder that the Rust toolchain is young enough to need patches.

## Installing Ultracite and running a first check

The README's quick start is one command. It runs an interactive setup that asks about your formatter and linter, framework, editor and AI agents, then installs and configures everything. Re-running it later adjusts the setup, so it is not a one-shot scaffold. If you use pnpm, Yarn or Bun, the README notes Ultracite detects your package manager, or you can invoke it with pnpm dlx, yarn dlx or bunx.

```bash
npx ultracite init
```

After setup, the check command lints without writing changes, and fix applies auto-fixes. Both accept an optional list of files or globs; omit them to run against the whole project. Unknown flags are forwarded to the underlying linter, so anything your chosen tool supports still works.

```bash
npx ultracite check
npx ultracite fix
```

For CI or scripted setup, init takes flags instead of prompts. The example below configures Biome, skips dependency installation, and stays quiet, which is the shape you want in a pipeline where installs are handled separately. The --quiet flag is auto-enabled in CI according to the README.

```bash
npx ultracite init --linter biome --pm bun --skip-install --quiet
```

Two more flags are worth knowing before you commit. --type-aware turns on type-aware linting, which is slower but catches errors that syntax-only rules miss. --install-skill installs a reusable Ultracite skill after setup. When something looks wrong, doctor verifies the setup and diagnoses configuration issues including linter version mismatches, and upgrade updates Ultracite and reinstalls your toolchain at the versions it supports.

```bash
npx ultracite doctor
npx ultracite upgrade
```

## The AI-agent handoff in ultracite fix is the unusual part

Most lint presets stop at reporting. Ultracite's fix command accepts --claude or --codex, which hands any remaining unfixable issues to the Claude Code or Codex CLI. The README states that the agent repairs them autonomously file by file, and that each fix is verified by a re-lint before it is marked done. That verification step is the reason to take the feature seriously rather than dismiss it as a gimmick: an agent that edits code and then re-runs the linter has a feedback signal, and the loop terminates when the linter stops complaining rather than when the model says it is finished. The obvious cost is that you are now running an autonomous editor over your working tree. Nothing in the README describes what happens when the agent cannot fix an issue, how many iterations it attempts, or whether its edits are staged separately for review. If you use this on a dirty working tree, you have no clean way to separate the agent's changes from your own. Run it on a committed branch, and treat the resulting diff as a pull request rather than a save.

## Where Ultracite is the wrong tool

The preset is opinionated by design, and that is a real constraint rather than a marketing line. If your team has spent two years tuning an ESLint config with custom plugins, local rules and per-directory overrides, adopting Ultracite means starting from its rules and re-adding your exceptions. The README says you can override anything, but it does not promise to merge your existing config; init configures a toolchain rather than importing one. A second limitation is toolchain churn. Ultracite pins supported versions of Biome, ESLint, Oxlint, Oxfmt, Prettier and Stylelint, and the upgrade command exists precisely because those versions move. The monorepo's own package.json carries a patch for oxfmt, which tells you the Rust formatter's release cadence can outpace Ultracite's support window. Expect to run upgrade, not to stay on whatever you installed a year ago. Third, type-aware linting is opt-in for a reason: it requires a working TypeScript program, and in a large monorepo the cost is measured in seconds, not milliseconds. The README's performance language applies to the Rust-based path, not to every configuration. Finally, if your project is not JavaScript or TypeScript, none of this applies.

## Ultracite against configuring Biome yourself

The closest comparison is not another lint preset. It is Biome's own init and recommended rules. Biome already ships a single binary that formats and lints, and it already provides a default rule set you can extend in biome.json. If you pick Biome through Ultracite, you get Biome plus a curated rule selection, an editor and agent configuration step, and a wrapper CLI. The difference in approach is who owns the rule list. With Biome directly, you own it and you update it when you read release notes. With Ultracite, the project owns it and you inherit changes through ultracite upgrade, which reinstalls the toolchain at versions Ultracite supports. That is a maintenance trade, not a capability gap. The same logic applies against a hand-written ESLint flat config: you get exactly the rules you wrote, and you get to keep them working across major ESLint releases yourself. Ultracite's advantage is that the same preset is available for three different toolchains, so a monorepo can standardise on one rule set even if individual packages use different linters. If every package already uses one linter and one config, that advantage disappears.

## Licence and the cost of keeping the preset current

Ultracite is MIT licensed, copyright Hayden Bleasel, as stated in the README and the repository's license.md. MIT permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive arrangement, and it matters here because the presets are meant to be extended by hand; you are allowed to fork the rule set and ship it inside a private package. This is not legal advice, and if you redistribute a modified preset you should read the licence text yourself. On maintenance, the last push to the repository was on 2026-09-09, and releases ultracite@7.11.1, 7.11.0 and 7.10.8 landed on 2026-09-09, 2026-09-06 and 2026-09-04 respectively. The version stream is dense enough that upgrade is a routine command rather than an annual event. Budget for it. The repository is not archived, and the release cadence is the evidence for that, not any claim about how well maintained it is. The practical upgrade cost is the diff in your generated config after each upgrade plus the possibility that a linter major version changes a rule's behaviour. The doctor command exists to catch version mismatches, so run it after upgrading rather than assuming the install succeeded.

## Conclusion

Adopt Ultracite if your repository has no linter config worth preserving, or if you want one ruleset shared by Biome, ESLint and Oxlint across a monorepo and you accept the preset's choices. Do not adopt it if your existing ESLint config encodes rules your team argues about, because the preset replaces that file rather than merging into it. Before committing, run npx ultracite init in a throwaway branch, then npx ultracite doctor to see which linter version the CLI expects, and read the generated config diff to check which of your current rules survive.

## FAQ

### What is Ultracite?

Ultracite is a zero-configuration preset and CLI for the Biome, ESLint and Oxlint toolchains, distributed on npm as the ultracite package. It installs hundreds of preconfigured rules for JavaScript and TypeScript through an interactive setup command, and it also generates ruleset and context files for AI coding agents.

### How do I install Ultracite in an existing project?

Run npx ultracite init in the project directory. The interactive setup asks which formatter and linter, framework, editor and AI agents you want, then installs and configures them; you can re-run it later to adjust the setup, and pnpm dlx, yarn dlx or bunx work as alternatives to npx.

### Which linters does Ultracite support?

Three toolchains: Biome, ESLint with Prettier and Stylelint, and Oxlint with Oxfmt. The README describes Biome as an all-in-one binary, ESLint as the largest plugin ecosystem, and Oxlint and Oxfmt as Rust-based tooling that runs dramatically faster than ESLint.

## Sources

- [haydenbleasel/ultracite on GitHub](https://github.com/haydenbleasel/ultracite)
- [License: MIT](https://github.com/haydenbleasel/ultracite/blob/main/LICENSE)
- [Project website](https://www.ultracite.ai/)
- [README](https://github.com/haydenbleasel/ultracite/blob/main/README.md)
- [Releases](https://github.com/haydenbleasel/ultracite/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/haydenbleasel-ultracite
