---
title: Configuration
description: Understand Ultracite's default presets, how framework-specific layers work, and which overrides to keep when your project needs custom rules.
---

One of Ultracite's best features is that it's zero-config out of the box — you can just extend the base preset and get going. However, every project is different, and you might want to customize certain rules or adapt Ultracite for different frameworks.

## Framework Presets

Ultracite provides framework-specific configurations that you can extend in addition to the base `core` configuration. This allows you to add framework-specific linting rules without bloating the base config or dealing with irrelevant rules.

The concept is the same across all supported linters — pull in the `core` preset, then layer on any framework presets you need — though the exact syntax differs per linter (Biome uses an `extends` array, while ESLint and Oxlint use imports; see the [provider pages](/docs/provider/biome) for each linter's syntax). For example, if you're using Biome with React and Next.js, you can pull in the following presets:

```jsonc title="biome.jsonc"
{
  "extends": [
    "ultracite/biome/core",
    "ultracite/biome/react",
    "ultracite/biome/next",
  ],
}
```

## Default Configuration

When you include the `core` preset, you're pulling in Ultracite's base configuration. This preset includes framework-agnostic rules and settings. Some notable aspects:

- **TypeScript strictness**: Enables strict checks and lint rules requiring robust typing. Discourages use of `any`, requires handling of `null/undefined`, and prefers explicit types where needed.
- **Best practices**: Common rules like no unused vars, no explicit eval, no prototype pollution, etc.
- **Accessibility**: ARIA attributes, semantic HTML, keyboard navigation, and other a11y rules are enabled by default.
- **Formatting conventions**: 2-space indentation, 80-character line width, semicolons, trailing commas, and double quotes.

All these defaults aim to enforce consistent style and prevent common errors without manual configuration.

## Type-Aware Rules

Ultracite ships an optional `type-aware` preset for Biome that enables project-graph rules — `noPrivateImports`, `noUndeclaredDependencies`, `noUnresolvedImports`, `noImportCycles`, and `noDeprecatedImports`. These rules require Biome's scanner, so they're slower and shipped as a separate layer:

```jsonc title="biome.jsonc"
{
  "extends": ["ultracite/biome/core", "ultracite/biome/type-aware"],
}
```

You can also enable this at setup time with `npx ultracite init --type-aware`. For Oxlint, the same flag installs `oxlint-tsgolint` for type-aware linting instead.

## Safe Fixes

Most Ultracite rules only report errors — they don't automatically modify your code. However, a few rules are configured with `"fix": "safe"`, meaning they will auto-fix when you run `ultracite fix`. These fixes are non-breaking and safe to apply automatically:

| Rule                 | Description                                           |
| -------------------- | ----------------------------------------------------- |
| `noUnusedImports`    | Removes unused import statements                      |
| `useBlockStatements` | Wraps single-line control flow bodies in curly braces |
| `useSortedClasses`   | Sorts Tailwind CSS classes into a consistent order    |

If you want to disable auto-fixing for any of these, override the rule in your config and remove the `fix` property.

## Overriding Rules

Each linter has its own way to disable or modify rules. For example, to disable the `useButtonType` rule for Biome, you can do the following:

```jsonc title="biome.jsonc"
{
  "extends": ["ultracite/biome/core"],
  "linter": {
    "rules": {
      "a11y": {
        "useButtonType": "off",
      },
    },
  },
}
```
