Oxlint in Cursor, on save and after agent edits
ultracite init --editors cursor writes .vscode/settings.json, so Cursor formats on save and applies your linter’s safe fixes, and installs the extension from Open VSX with the cursor launcher. Cursor’s agent applies AGENTS.md as a rule and reads linter errors to fix issues. --hooks cursor adds an afterFileEdit hook that fixes each file the agent edits, but nothing the hook prints reaches the agent.
Cursor by AnysphereChecked against Cursor 3.24
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true,Format on save
"emmet.showExpandedAbbreviation": "never",
"js/ts.tsdk.path": "node_modules/typescript/lib",The project’s TypeScript
"js/ts.tsdk.promptToUseWorkspaceVersion": true,
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
},
"[css]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[graphql]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[handlebars]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[html]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[json]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[less]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[scss]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[typescript]": {Oxfmt formats it
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[vue-html]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[vue]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"[yaml]": {
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.oxc": "explicit"Oxlint’s safe fixes
}
}init does in Cursor- 1Writes
.vscode/settings.jsonA new file, or merged into yours setting by setting, with your comments and other settings kept. - 2Installs
oxc.oxc-vscodeWithcursor --install-extension, when it creates the settings file. - 3With
--hooks cursor, writes.cursor/hooks.jsonRunsnpx ultracite fix --hookon each file Cursor’s agent edits.
- 4If
initcouldn’t runcursor, install the Oxc extension from the Extensions view (Cmd+Shift+X), or Biome’s if you picked Biome. - 5With
--hooks cursor, open Customize → Hooks and check thatafterFileEditis listed. - 6Save a file: Oxfmt formats it and Oxlint’s safe fixes apply.
Three toolchains, one settings.json
init writes the settings for the toolchain you pick, so Cursor formats with the same tool as ultracite fix and applies its fixes when you save.
Oxlint + OxfmtDefault
- Extension
- oxc.oxc-vscode
- Formats with
- oxc.oxc-vscode
- On save
- source.fixAll.oxc
--linter oxlint
- Extension
- biomejs.biome
- Formats with
- biomejs.biome
- On save
- source.fixAll.biomesource.organizeImports.biome
--linter biome
- Extensions
- dbaeumer.vscode-eslintesbenp.prettier-vscode
- Formats with
- esbenp.prettier-vscode
- On save
- source.fixAll.eslintsource.organizeImports
--linter eslint
Where Cursor gets its extensions
Cursor reads .vscode/settings.json as VS Code does, but installs extensions from Open VSX through its own proxy, and team admins can restrict which ones install.
- Extensions
- From Open VSX, through Cursor’s own proxy (
marketplace.cursorapi.com), which scans each extension before offering it.oxc.oxc-vscode,biomejs.biome,dbaeumer.vscode-eslintandesbenp.prettier-vscodeare all there. - Launcher
cursor, which takes--install-extensionlike VS Code’scode. On macOS,Shell Command: Install 'cursor' commandputs it on your PATH.- Workspace settings
- Cursor is built on VS Code and reads
.vscode/settings.json. The agent asks for your approval before it edits workspace settings. - Workspace trust
- Off by default, so the settings apply as soon as you open a folder. If you turn it on with
security.workspace.trust.enabled, Restricted Mode breaks AI features and project hooks wait for trust. - Team controls
- Admins can limit installs to approved publishers or extension IDs (
AllowedExtensions) and set an install cooldown for new versions. Either can block or delay the extensioninitinstalls. - Hooks
- Cursor reloads
.cursor/hooks.jsonwhen it changes. The Hooks tab in Customize and the Hooks output channel show what ran and any errors.
The hook fixes, the agent reads the lints
Cursor merges every rule that applies, team rules first, then project rules, then user rules, and AGENTS.md counts as a project rule with no frontmatter. Since 0.44 the agent reads linter errors to fix issues. The afterFileEdit hook from --hooks cursor fixes and formats each file the agent edits, but Cursor defines no output for that event, so the agent never sees what the hook printed.
- 1
Team rulesSet in the dashboard on Team and Enterprise plans. They take precedence, and enforced ones can’t be turned off. - 2
.cursor/rules/*.mdcProject rules, applied by theiralwaysApply,globsordescriptionfrontmatter. A plain.mdfile here is ignored. - 3
AGENTS.mdUltracitePlain Markdown at the project root, applied as a rule without frontmatter. This is whereinitwrites Ultracite’s rules. - 4
CLAUDE.mdRead the same way asAGENTS.md, and applied to every conversation. - 5
frontend/AGENTS.mdApplied when the agent works on files in that folder, combined with the parent files; the more specific one wins. - 6
User rulesYour own rules from Customize → Rules, or files in~/.cursor/rules. Lowest precedence.
{
"hooks": {
"afterFileEdit": [
{
"command": "npx ultracite fix --hook"
}
]
},
"version": 1
}- 01The agent edits a file and writes it to disk, and Cursor fires
afterFileEditwith the file’s path. - 02
npx ultracite fix --hookfixes and formats that one file. If problems remain, the hook fails; Cursor logs it in the Hooks output channel and the agent carries on. - 03The Oxc, Biome or ESLint extension reports what’s left as linter errors, as it does for your own edits.
- 04The agent reads those linter errors and fixes what it can, so the lint loop runs through the editor, not the hook.
Worth knowing about Cursor
Tab edits skip the hook
Cursor fires
afterTabFileEditfor Tab completions andafterFileEditonly for the agent, so Ultracite’s hook doesn’t touch what you accept from Tab. Format on save covers those edits when you save the file.Claude Code hooks run too
With Third-Party Imports on, the default, Cursor also loads hooks from
.claude/settings.jsonand runs every matching hook from every source. A project set up with--hooks claudeas well as--hooks cursorcan run Ultracite twice after one edit.Cloud agents keep the hook
Cloud agents run the command hooks in your repository’s
.cursor/hooks.json,afterFileEditincluded. They skip hooks during early read-only turns and start running them once the agent has a writable environment.
Cursor questions, answered
- How do I format on save with Oxlint in Cursor?
- Run
npx ultracite init --editors cursor. It writes.vscode/settings.jsonwith Oxfmt (oxc.oxc-vscode) as the formatter andsource.fixAll.oxcon save, and installs the Oxc extension withcursor --install-extensionwhen it creates the file. - Does Cursor use the VS Code Marketplace?
- No. Cursor installs extensions from Open VSX, through its own proxy that scans them first. The Oxc, Biome, ESLint and Prettier extensions Ultracite uses are on Open VSX under the same IDs.
- Why didn’t the Biome extension install in Cursor?
initinstalls it only when it creates.vscode/settings.json, and only ifcursoris on your PATH (on macOS, runShell Command: Install 'cursor' command). On a team plan, an allowed extensions list or install cooldown can block or delay it. Install it from the Extensions view instead.- Does Cursor read AGENTS.md?
- Yes. Cursor applies
AGENTS.mdat the project root as plain-Markdown rules alongside.cursor/rules, and nestedAGENTS.mdfiles apply to their folder. It readsCLAUDE.mdthe same way. - Does the Cursor hook tell the agent what’s left to fix?
- No. Cursor defines no output for
afterFileEdit, so the hook fixes and formats the file and stops there. The agent finds what’s left through the linter errors it reads in the editor. - Why isn’t my Cursor hook running?
- Project hooks only run in a trusted workspace. Workspace trust is off by default in Cursor, so this only matters if you’ve set
security.workspace.trust.enabled; then trust the folder.
Keep going
- AgentCursor CLIThe Cursor agent in your terminal, interactive or headless.
- EditorVS CodeMicrosoft’s code editor, with GitHub Copilot’s agent built in and extensions from the Visual Studio Marketplace.
- EditorDevin DesktopCognition’s AI IDE, formerly Windsurf, built on Code OSS, with the Devin Local agent.
- DocsEditor setupEvery editor
initconfigures, and the extension each toolchain needs.
Ship less slop
One command sets up your linter, formatter, editor and agents. Works with Oxlint, Biome and ESLint.