Skip to content
Ultracite
Esc
↑↓navigate↵open⌘Jpreview

Claude Code, held to your lint rules

Claude Code reads Ultracite’s rules from AGENTS.md, or through an import when your project has its own CLAUDE.md. A PostToolUse hook runs ultracite fix on every file Claude writes and hands back what’s left, so Claude fixes it in the same turn.

Claude Code by AnthropicChecked against October 2026

# Ultracite Code Standards

This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting.

## Quick Reference

- **Format code**: `npx ultracite fix`
- **Check for issues**: `npx ultracite check`
- **Diagnose setup**: `npx ultracite doctor`

Oxlint + Oxfmt (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable.

…
Ultracite’s rules
# Your project notes

@AGENTS.md
Only if you have one
Where Claude Code looks for instructions
  1. 1Managed CLAUDE.mdYour organization’s managed policy, when there is one.
  2. 2~/.claude/CLAUDE.mdYour instructions for every project.
  3. 3CLAUDE.md or .claude/CLAUDE.mdThe project’s own instructions, from the working directory up. If either exists, Claude reads them instead of AGENTS.md.
  4. 4AGENTS.mdUltraciteRead when the project has no CLAUDE.md, or through an @AGENTS.md import when it does.
  5. 5src/**/CLAUDE.mdA subdirectory’s instructions, loaded when Claude first reads or edits a file there.

How Claude Code reads the rules

Claude Code builds its instructions from a stack of files, broadest first. AGENTS.md sits in the middle of it, as the project’s instructions whenever there’s no CLAUDE.md to take that place.

Project file
CLAUDE.md or .claude/CLAUDE.md, or AGENTS.md when neither exists.
Personal
~/.claude/CLAUDE.md for every project and a gitignored CLAUDE.local.md for one. Both load alongside AGENTS.md, except that CLAUDE.local.md counts as a CLAUDE.md.
Size
Aim for under 200 lines per file: longer files cost context and adherence. Imports don’t reduce that, since imported files load at launch too.
Imports
@path lines expand at launch, up to four levels deep. A path outside the project asks for approval once.
Both at once
Set Project instructions to claude-md-and-agents-md in /config to load both files without an import. It’s a personal setting, not a project one.
Check it
/context lists every instructions file Claude loaded.

A hook on every Write and Edit

init --hooks claude adds a PostToolUse hook for Claude’s Write and Edit tools. It fixes only the file Claude touched, and when problems remain it exits with code 2, which Claude Code turns into feedback Claude reads before its next step.

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "command": "npx ultracite fix --hook",
            "type": "command"
          }
        ],
        "matcher": "Write|Edit"
      }
    ]
  }
}
init --hooks claude
  1. 01Claude writes or edits a file with its Write or Edit tool.
  2. 02Claude Code runs the hook, which reads the edited file’s path from the hook payload and runs ultracite fix on just that file.
  3. 03Safe fixes and formatting are applied. If nothing is left, the hook exits 0 and Claude carries on.
  4. 04If problems remain, the hook prints them to stderr and exits 2, and Claude reads them and fixes them before its next step.

Worth knowing about Claude Code

  • Nested instructions load on demand

    Claude Code loads a subdirectory’s CLAUDE.md (or AGENTS.md, when it has no CLAUDE.md) the first time Claude reads or edits a file there, so a workspace’s own instructions arrive with its code.

  • Path-scoped rules for the rest

    Files in .claude/rules/ with a paths field load only when Claude works on matching files. Ultracite’s rules apply everywhere, so they stay in AGENTS.md; framework-specific notes of your own fit well in a path-scoped rule.

  • Imports are relative

    An @path import resolves relative to the file it’s in and can nest four levels deep. That’s why the import in .claude/CLAUDE.md is @../AGENTS.md.

  • The Ultracite skill

    Claude Code loads skills from .claude/skills/. When init installs the Ultracite skill in a project with a .claude folder, it installs it there, so Claude knows how to run init, check, fix and doctor.

Claude Code questions, answered

Does Claude Code read AGENTS.md or CLAUDE.md?
Both, but not at once by default. Claude Code reads AGENTS.md (since v2.1.277) only when there’s no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in your working directory or above it. When your project has a CLAUDE.md, ultracite init --agents claude adds an @AGENTS.md import to it, so Claude loads both.
How does the hook tell Claude what’s left?
It prints what ultracite fix couldn’t settle to stderr and exits with code 2. Claude Code shows a PostToolUse hook’s stderr to Claude on that exit code, so Claude sees the remaining problems in the same turn and fixes them before moving on.
Can Claude fix what autofix can’t, outside a session?
Run npx ultracite fix --claude. After the safe fixes, it hands each file with problems left to the Claude Code CLI (claude -p in acceptEdits mode, limited to reading and editing files), then lints again, so the result decides what counts as fixed.
How do I check Claude loaded the rules?
Run /context in a session and look under Memory files. AGENTS.md shows there when Claude reads it directly; with a CLAUDE.md that imports it, the import is expanded into that file.
I set Ultracite up for Claude before. Do I need to do anything?
Yes, unless you’ve turned it off. Running init again takes Ultracite’s block out of the .claude/CLAUDE.md earlier versions wrote, removes the file if nothing else is left in it, and imports AGENTS.md from whatever CLAUDE.md remains, because a leftover .claude/CLAUDE.md stops Claude from reading AGENTS.md.

Ship less slop

One command sets up your linter, formatter, editor and agents. Works with Oxlint, Biome and ESLint.