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

VS Code, with fixes on every save you make

ultracite init --editors vscode writes .vscode/settings.json, so VS Code formats with your toolchain’s extension and applies its fixes when you save, and installs that extension with code --install-extension. GitHub Copilot reads Ultracite’s rules from AGENTS.md, and init --hooks copilot adds a hook that fixes each file it edits.

VS Code by MicrosoftChecked against VS Code 1.141.0

{
  "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
  }
}
Oxlint + Oxfmt
What init does in VS Code
  1. 1Writes .vscode/settings.jsonA new file, or merged into yours setting by setting, with your comments and other settings kept.
  2. 2Installs oxc.oxc-vscodeWith code --install-extension, when it creates the settings file.
  3. 3With --hooks copilot, writes .github/hooks/ultracite.jsonRuns npx ultracite fix --hook on each file VS Code’s agent edits.
Then, in VS Code
  1. 4If VS Code opened the folder in Restricted Mode, trust it from the banner. Until you do, extensions that haven’t opted in to Restricted Mode don’t run.
  2. 5If init asked you to, install oxc.oxc-vscode from the Extensions view, or the extension for the toolchain you picked.
  3. 6Save a file with Cmd+S or Ctrl+S: Oxfmt formats it and Oxlint’s safe fixes apply.

Three toolchains, one settings.json

init writes the settings for the toolchain you pick, so VS Code 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

  • Biome

    Extension
    biomejs.biome
    Formats with
    biomejs.biome
    On save
    source.fixAll.biomesource.organizeImports.biome

    --linter biome

  • ESLint + Prettier + Stylelint

    Extensions
    dbaeumer.vscode-eslintesbenp.prettier-vscode
    Formats with
    esbenp.prettier-vscode
    On save
    source.fixAll.eslintsource.organizeImports

    --linter eslint

What decides whether a save formats

VS Code formats and fixes through your toolchain’s extension, so a save does both only when that extension runs in the profile you’re using, the folder is trusted, and you saved the file yourself.

Extensions
From the Visual Studio Marketplace. init installs them with code --install-extension, the same command you can run by hand.
The code command
Windows and Linux installs put code on your PATH. On macOS, run “Shell Command: Install ‘code’ command in PATH” first, or init can’t install the extension.
Profiles
code --install-extension targets a specific profile only when you pass --profile <name>, and init doesn’t. If this folder uses another profile, install the extension in that profile.
Restricted Mode
VS Code opens an unfamiliar folder in Restricted Mode, which disables extensions that haven’t opted in, limits others and skips some workspace settings. Trust the folder from the banner.
Explicit saves
init sets each fix to "explicit", so it runs when you save with Cmd+S or Ctrl+S, not on auto save.
Auto save
Change a fix to "always" to also run it on auto saves from focus or window changes. Auto save after a delay doesn’t trigger it either way.

Two Copilot harnesses, one AGENTS.md

VS Code runs Copilot two ways, as Copilot sessions on the Agent Host or as the Local agent in the extension host, and both read AGENTS.md alongside your other instruction files. The Local agent saves its edits without running format on save, so the fixes wait until you choose Keep, or run after each edit with the hook init --hooks copilot writes.

Where the agent looks for instructions
  1. 1~/.copilot/copilot-instructions.mdYour instructions for every project, in Copilot sessions. The Local agent keeps user instructions in your VS Code profile instead.
  2. 2.github/copilot-instructions.mdProject-wide instructions for both. The Local agent reads it while github.copilot.chat.codeGeneration.useInstructionFiles is on.
  3. 3.github/instructions/**/*.instructions.mdAttached when the applyTo glob matches a file the agent creates or modifies, or loaded when the description fits the task. The Local agent also reads .claude/rules.
  4. 4AGENTS.mdUltraciteWhere init writes Ultracite’s rules. Read by Copilot sessions, and by the Local agent while chat.useAgentsMdFile is on. Files in subfolders also need chat.useNestedAgentsMdFiles, which is off by default.
  5. 5CLAUDE.md, .claude/CLAUDE.mdAlso read by the Local agent while chat.useClaudeMdFile is on. Every file that applies is added; none replaces another.
{
  "hooks": {
    "postToolUse": [
      {
        "command": "npx ultracite fix --hook",
        "type": "command"
      }
    ]
  },
  "version": 1
}
init --hooks copilot
  1. 01Copilot edits a file. The Local agent saves it with format on save and code actions skipped, and marks the edit as pending.
  2. 02With init --hooks copilot, .github/hooks/ultracite.json runs ultracite fix --hook on that file. Copilot sessions run it as the Copilot CLI does; the Local agent maps its format onto its own.
  3. 03The agent can read what’s left with #read/problems, which returns the Problems panel’s diagnostics from the Oxc, Biome or ESLint extension.
  4. 04When you choose Keep, VS Code saves the file again as an explicit save, so editor.formatOnSave and editor.codeActionsOnSave run on the agent’s code.
Agent pageUltracite for GitHub Copilot

Worth knowing about VS Code

  • Agents need a trusted folder

    Restricted Mode turns agents off for that workspace, and trust is shared with the Agents window, so an untrusted folder runs no agent in either. Hook files in .github/hooks are subject to Workspace Trust too.

  • Claude Code hooks are opt-in

    The Local agent reads hooks from .claude/settings.json only when chat.useClaudeHooks is on, which it isn’t by default, and then ignores their matchers. init --hooks copilot writes a .github/hooks file it reads without a setting.

  • Check which rules loaded

    Expand References under a Copilot response to see which instruction files went into the request, or run “Chat: Open Customizations” to see what the selected harness discovered, AGENTS.md included.

VS Code questions, answered

Why doesn’t VS Code format on save after ultracite init?
Usually the extension isn’t running. Check that oxc.oxc-vscode, or your toolchain’s extension, is installed in the profile this folder uses, and that the folder is trusted: Restricted Mode disables extensions that haven’t opted in.
Does auto save apply Oxlint fixes in VS Code?
Not with the settings init writes. Fixes set to "explicit" run only when you save yourself. Set one to "always" to also run it on auto saves from focus or window changes; auto save after a delay still won’t trigger it.
Does GitHub Copilot in VS Code read AGENTS.md?
Yes, in Copilot sessions and in the Local agent, where chat.useAgentsMdFile turns it on or off. VS Code adds it to .github/copilot-instructions.md and any matching .instructions.md files rather than choosing one.
Can Copilot see Oxlint errors in VS Code?
Yes. The #read/problems tool gets diagnostics from the Problems panel, which is where the Oxc, Biome and ESLint extensions report them. Reference it in a prompt, or add init --hooks copilot so each edited file is fixed as Copilot goes.
Why didn’t init install the VS Code extension?
init installs it only when it creates .vscode/settings.json, and only if code is on your PATH. On macOS, run “Shell Command: Install ‘code’ command in PATH” from the Command Palette, then code --install-extension oxc.oxc-vscode.
Why isn’t Copilot’s code formatted in VS Code?
The Local agent saves its edits without running format on save or code actions. Choosing Keep saves the file again and runs them, and npx ultracite init --hooks copilot adds a hook that runs ultracite fix after each edit instead.

Ship less slop

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