Key takeaways
- Every AI coding tool reads its own file in its own path — there is no shared format that all of them load natively.
- Maintained by hand, those files drift: a fix in one never reaches the others, and the same bug returns through a different tool.
- The fixes people reach for — pick one tool, symlink, or a homegrown script — each break for a concrete reason.
- What works: one canonical library, authored and versioned once, compiled to each tool’s native format and deployed per project.
The four-files problem
Pick any team shipping real software in 2026 and you’ll find more than one AI coding tool in the mix. One developer lives in Cursor, another drives Claude Code from the terminal, a third is on Windsurf for the JetBrains support, and Copilot is on in everyone’s editor because it’s already paid for. That’s not indecision — it’s the normal state of a team that lets people use what makes them productive.
The catch is that each tool reads a different file from a differentpath. The same rule — “use our error wrapper, never throw raw,” “tests colocate with source,” “no anyin new code” — has to exist in all of them, and each speaks its own dialect.
| Tool | Rules file / path | Format |
|---|---|---|
| Claude Code | CLAUDE.md + .claude/skills/<name>/SKILL.md | Markdown (facts) + YAML-frontmatter skills |
| Cursor | .cursor/rules/*.mdc (legacy .cursorrules) | Markdown + frontmatter (description, globs, alwaysApply) |
| Windsurf | .windsurf/rules/*.md (legacy .windsurfrules) | Markdown + trigger frontmatter; 12,000-char file cap |
| GitHub Copilot | .github/copilot-instructions.md | Markdown; path rules in .github/instructions/*.instructions.md |
Four files, four locations, three frontmatter conventions, and one of them buried in a .github/ subdirectory with a hard character limit. The content overlaps almost entirely — and that overlap is exactly what makes the divergence so easy to miss. For a format-by-format breakdown of what each one can express, see SKILL.md vs CLAUDE.md vs .cursorrules vs AGENTS.md.
Six ways this drifts
“Just keep them in sync” sounds trivial until you watch how the duplication actually rots. Here’s where it bites, roughly in the order teams hit it:
- Drift after a bugfix. You debug a nasty failure, learn the lesson, and encode it as a rule in the tool you were using —
.cursor/rules/, say. The other three files never hear about it. Months later the same class of bug returns through Claude Code or Copilot, which never got the memo. - Copy-paste rot.The honest fix is to paste the new rule into all four files. It works once. By the third edit you tweak the wording in one, skip another because it has a different frontmatter shape, and now the “identical” rules quietly disagree.
- No version history or changelog. There’s no
npm auditfor prompts. Git tracks that a line in a Markdown file changed, but nothing tells you whichfile is authoritative, when a rule was added, or why. You can’t diff “the rule” — only four copies of it. - No reuse across projects. Your hard-won
TypeScriptconventions live in thisrepo’s four files. Spin up the next project and you start from a blankCLAUDE.md, copy-pasting from the last repo and hoping it was the up-to-date one. - No deactivation path. A rule that made sense for an old framework version is now actively wrong. Turning it off means finding and deleting it in all four files — so instead it lingers, and the agent keeps following stale guidance.
- Onboarding cost.A new hire clones the repo and gets whatever’s committed — which may be three current files and one that’s six weeks behind. Now their agent behaves subtly differently from everyone else’s, and nobody can say which file is the real one.
Strategies people try (and why they break)
Once the drift is obvious, three fixes suggest themselves. Each is a reasonable instinct, and each breaks for a concrete reason.
A. “Just use one tool”
The cleanest theory: standardize the whole team on one agent and the multi-file problem evaporates. In practice it doesn’t hold. Different developers are genuinely faster in different tools — Cursor’s autocomplete versus Claude Code’s autonomous multi-file edits versus Windsurf being the only one with full JetBrains support. And different tasksfavor different tools even for the same person: a terminal agent for a big refactor, an inline assistant for quick edits. Mandating one tool trades a real productivity loss for a tidiness win, so teams quietly route around the mandate and you’re back to multiple files anyway.
B. Symlink the files together
The next instinct is to make the files be the same file: ln -s CLAUDE.md .cursorrulesand call it done. It falls apart because the formats aren’t interchangeable:
- Cursor’s
.mdcrules expect frontmatter (description,globs,alwaysApply) that a plainCLAUDE.mddoesn’t carry — a.mdfile with no frontmatter in.cursor/rules/is simply ignored. - Windsurf uses a
triggerfield and caps each file at 12,000 characters; Copilot wants an exact path and its ownapplyToglobs. - Copilot’s file lives in
.github/— a subdirectory, not the repo root — so a flat symlink doesn’t even land in the right place.
A symlink forces one syntax onto tools that reject it. The content might be 80% portable, but the 20% that isn’t is exactly the structured part that makes each file work.
C. Generate them from a single source
This is the right idea: keep one canonical file and write a script that emits the four tool-specific versions. The architecture is sound — it’s the same logic behind converting .cursorrules to CLAUDE.md, AGENTS.md & Copilot. The trouble is that a hand-rolled script becomes its own maintenance burden. You now own the frontmatter mapping for every format, the character-limit splitting for Windsurf, the path conventions, and a deploy step into N repos — and you get to update all of that every time a tool changes its rules system (which they do; Cursor moved from .cursorrules to .cursor/rules/, Copilot added .instructions.md). You’ve replaced four files you maintain by hand with one script you maintain by hand.
What good looks like: one canonical library
Strategy C is correct about the shape of the solution — single source, compile out — and wrong only about hand-building it. Pull the compile-and-deploy machinery out of a one-off script and into a real tool, and the model becomes clean:
- Author once. A rule or skill exists in exactly one place — your library — not four files in every repo.
- Version once. The rule itself has history: when it was added, what changed, why. You diff the rule, not four copies of it.
- Compile to native formats. The library emits
CLAUDE.md/SKILL.md,.cursor/rules/*.mdc,.windsurf/rules/, and.github/copilot-instructions.md— each with the right frontmatter, paths, and limits. - Deploy to every project.Push the same canonical rules into each repo instead of copy-pasting last project’s stale version.
- Drift becomes visible.Because there’s a source of truth, a project that’s behind is a diff you can see, not a surprise you discover six months later through a recurring bug.
That’s exactly what Skillwrightis built to do: a desktop app that holds your AI coding rules and skills in one canonical library and compiles them to every IDE’s native format — SKILL.md/CLAUDE.md, .cursor/rules, .windsurf/rules, and copilot-instructions.md — then deploys to each project from a single place. The four files stop being four things you maintain and become an output. If you want a running start, the templates library has MIT-licensed rules and skills you can drop straight in, and the pricing page covers the founding plan.
Putting it in version control / sharing with a team
Whichever path you take, the rules that govern a project belong in that project’s repo. The reasoning is the same as for any other config:
- Commit project rules.Editor-local settings don’t travel — not to a teammate, not to CI, not to your other laptop. A committed
.cursor/rules/or.claude/skills/directory is reviewed in PRs, versioned with the code it governs, and identical for everyone who clones the repo. - Keep personal preferences out of it.Your own global rules — formatting habits, the way you like commit messages — belong in your user-scoped config, not the shared repo. Commit the team’s conventions; keep your idiosyncrasies to yourself.
- The onboarding win is the real payoff.When the canonical rules are committed and current, a new hire clones the repo and their agent is configured correctly on day one — no “here’s the doc you have to paste into your editor,” no drift between their setup and yours. That’s the difference between rules as tribal knowledge and rules as infrastructure.
The team angle
Committing four files solves distribution— everyone gets the same files. It doesn’t solve synchronization — keeping those four files agreeing with each other as conventions evolve. A canonical library that compiles into the repo handles both: the team shares one source, and the per-tool files are regenerated rather than hand-edited into disagreement.
Where to go next
Multi-tool rule management comes down to one decision: maintain N files by hand, or maintain one source and compile the rest. If you’re ready to set this up, three reads cover the practical ground:
- Convert .cursorrules to CLAUDE.md, AGENTS.md & Copilot — the field-by-field mapping, so you know exactly what a compile step has to produce.
- SKILL.md vs CLAUDE.md vs .cursorrules vs AGENTS.md — what each format can and can’t express, so you pick the right home for each rule.
- The AGENTS.md standard — the one cross-tool file, how far portability actually gets you, and why Claude Code still needs its own.
Or skip the comparison shopping and let Skillwright own the compile-and-deploy step for you.
Frequently asked questions
How do I use the same rules in Cursor and Claude Code?
Keep one canonical version of the convention and emit each tool's native file from it. Cursor reads .cursor/rules/*.mdc (with description/globs/alwaysApply frontmatter); Claude Code reads CLAUDE.md for facts and .claude/skills/ for procedures. A plain symlink doesn't work because the syntaxes differ — Cursor's .mdc needs frontmatter a CLAUDE.md doesn't have. Either port the change by hand each time, or compile both from a single source.
Can I share AI coding rules across a team?
Yes — commit them. Project-scoped rule files (.cursor/rules/, .claude/skills/, .github/copilot-instructions.md, .windsurf/rules/) live in the repo, so anyone who clones it gets the same conventions and a new hire's agent is configured on day one. The hard part isn't sharing one file; it's keeping all four in sync as the conventions evolve, which is where a canonical library beats four committed files.
Should AI rules live in the editor or in version control?
Version control, for anything project-specific. Editor-local settings don't travel to teammates or CI, and they vanish when you switch machines. Commit project rules next to the code they govern so they're reviewed, versioned, and shared. Keep only genuinely personal preferences (your own global rules) outside the repo.
What's the best way to manage AI rules across multiple tools?
Author each rule once in a canonical library, compile it to every tool's native format, and deploy to each project — rather than hand-editing four files. That gives you one place to make a change, version history on the rules themselves, reuse across projects, and visible drift when a project falls behind. Skillwright is built for exactly this workflow.
Do I need a separate rules file for every AI tool?
On disk, effectively yes — each tool reads its own path and format, and AGENTS.md (the one cross-tool standard) isn't read natively by Claude Code. But you don't need to author them separately. The practical move is one source of truth plus a compile step that produces each tool's file, so 'four files' becomes an output, not four things you maintain.