Claude Code Skills·Claude Skills·The open SKILL.md registry for Claude
HomeLearn › Claude Code SKILL.md vs Cursor Rules vs Windsurf Rules

Claude Code SKILL.md vs Cursor Rules vs Windsurf Rules

Published 1 June 2026 · 14 min read · By a long-time Claude Code practitioner

Three AI coding agents, three different answers to the same question: how do you give an agent persistent behavioural instructions that survive across sessions? Claude Code uses SKILL.md files with auto-discovery. Cursor uses a .cursorrules file that's always loaded. Windsurf uses .windsurfrules with similar always-on semantics. This guide walks through how each works, where they differ, and how to migrate between them.

By the end you'll know which model fits your team, how to convert rules between the three formats, and how the interoperability layer is shaking out as more projects start supporting all of them.

In this guide

TL;DR — the comparison matrix

If you're skimming, here's the difference in one table. All three tools solve the same surface problem: I want the agent to follow my conventions without me re-explaining them every session. They differ on how the instructions get into the model's context, how you scope them, and how you distribute them.

DimensionClaude Code (SKILL.md)Cursor (.cursorrules)Windsurf (.windsurfrules)
File location~/.claude/skills/<slug>/SKILL.md or .claude/skills/ in repo.cursorrules at repo root.windsurfrules at repo root (or global_rules.md for global)
Loading modelDescription-triggered, on-demandAlways loaded into system promptAlways loaded into system prompt
Multi-rule supportNative — one directory per skill, hundreds coexistSingle file (legacy); .cursor/rules/*.mdc for scoped rules (newer)Single file; .windsurf/rules/ directory for memories
ScopeProject + global, both activeProject only (with newer global rules option)Project + global
DiscoverabilityDescription scanned at startup; body loads on intent matchEager — entire file in every requestEager — entire file in every request
PackagingStandalone Git repo per skill; install by copying directoryCopy/paste a file; awesome-cursorrules listsCopy/paste a file
Token costDescription tokens only until triggeredFull file tokens on every turnFull file tokens on every turn
FrontmatterYAML required: name, description, optional allowed-tools, modelNone (plain text/markdown)None (plain text/markdown), but .mdc files in newer dir support frontmatter globs

The headline difference is the loading model. Claude Code treats skills like libraries — you install them once, the runtime decides what to pull in. Cursor and Windsurf treat rules like a project-level system prompt — everything is always there, you pay the token cost on every request. Both philosophies have real trade-offs, which the rest of this article unpacks.

How Claude Code skills work

A Claude Code skill is a directory with a SKILL.md file inside. The minimum viable skill is two lines of YAML frontmatter plus a body:

---
name: postgres-migrations
description: Use when writing, reviewing, or rolling back PostgreSQL schema migrations. Covers transactional DDL, backfill patterns, and zero-downtime renames.
---

# PostgreSQL Migrations

Always wrap schema changes in a transaction unless the operation explicitly forbids it (e.g. CREATE INDEX CONCURRENTLY). For backfills, batch updates in chunks of 5,000 rows...

Drop that file at ~/.claude/skills/postgres-migrations/SKILL.md and Claude Code picks it up on next launch. The key mechanic: at startup, Claude scans every skill's frontmatter — just the description, not the body. The descriptions are added to a lightweight index. When you start a conversation and say "help me write a migration to add a nullable column to the users table," Claude matches your intent against those descriptions, decides postgres-migrations is relevant, and loads the full body into context for that turn.

This description-as-trigger pattern is the whole point. It means you can have 200 skills installed and never pay the token cost of skills you don't use today. The cost shows up only when a skill is actually loaded. Writing the description well is therefore the highest-leverage thing you do when authoring a skill — it's the function signature the runtime matches against.

Two more important properties:

The format also supports allowed-tools in frontmatter (gate which tools a skill can invoke), model hints, and a few other fields. But the essence — auto-discovery, description-triggered loading, multi-skill composition — is what differentiates the model from Cursor's and Windsurf's.

How Cursor .cursorrules works

Cursor's classic mechanism is a single file: .cursorrules at your project root. It's plain text (markdown is fine, no YAML frontmatter required). Whatever you write in it gets prepended to Cursor's system prompt on every request — chat completions, tab completions, agent runs, all of them.

# Project conventions

We're a TypeScript monorepo using pnpm workspaces.
- Always use named exports, never default exports.
- Test files live next to source files as <name>.test.ts.
- We use Vitest, not Jest. Don't import from "jest".
- API responses follow our Result<T, E> pattern in src/lib/result.ts.

# Style

- Prefer early returns over nested ifs.
- No barrel files (index.ts re-exports) — they break tree shaking.

The model is brutally simple: one file, always loaded, scoped to the project. That simplicity is its strength. There's no discovery layer to learn, no frontmatter to write, no convention about how to name things. You write the rules, Cursor reads them. Done.

The trade-offs are real, though. Every turn pays the .cursorrules token cost, which can add up — a 2,000-line rules file is a meaningful tax on every tab completion. Teams that grow their rules file organically end up with stale guidance baked into every request and no way to scope rules to specific paths ("only apply these React conventions in the apps/web/ directory").

Cursor has been adding more mechanisms over time. The newer pattern is a .cursor/rules/ directory with multiple .mdc files. Each file can carry frontmatter that scopes the rule by glob:

---
description: React component conventions
globs: apps/web/**/*.{tsx,jsx}
alwaysApply: false
---

Use function components, never class components.
Memoize expensive children with React.memo.
...

This project rules directory narrows the gap with Claude Code's model — you get per-rule scoping and the option to not always-apply. But the loading mechanic is still glob-based rather than intent-based: if the file you're editing matches the glob, the rule loads. It's a closer cousin to Claude Code's model than the classic .cursorrules, but still not the same thing.

Cursor also added a global rules surface in settings — a text area you fill in that applies across all projects. That covers the equivalent of Claude Code's ~/.claude/skills/ global scope, just with a UI rather than a directory of files.

How Windsurf .windsurfrules works

Windsurf, the Codeium-built editor with the Cascade agent, follows a model very close to Cursor's. A .windsurfrules file in your project root carries plain-text instructions that load on every Cascade turn. Format-wise, it's interchangeable with .cursorrules in practice — same flat text, same always-on loading model, same conventions about writing in markdown.

# Cascade rules for this project

## Stack
- Next.js 14 app router
- Drizzle ORM + Postgres
- Tailwind + shadcn/ui

## Behaviour
- When asked to add a route, also add a corresponding Playwright test in e2e/.
- Never write raw SQL outside src/db/migrations/.
- Server actions go in app/_actions/, never inline in components.

Windsurf supplements this with a couple of mechanisms that differ from Cursor:

The Cascade workflow is more agentic than Cursor's chat — it'll run multi-step changes, then summarise. Rules anchor that behaviour: without them, Cascade is happy to deviate from your conventions; with them, you get consistency across sessions and team members.

From a comparison standpoint, treat Windsurf and Cursor as siblings in this dimension. The trade-offs are nearly identical: simple always-on loading model, fixed token cost per turn, optional newer mechanisms for scoping. If you know how to write .cursorrules, you can write .windsurfrules in 90 seconds.

Side-by-side: scope, discovery, packaging, ecosystem

Let's zoom out on the dimensions that actually matter when you're picking a model for your team.

Scope

All three support project-scoped rules. Claude Code and Windsurf both support global rules out of the box (filesystem locations); Cursor offers global rules through its settings UI. If your team works across many repos and you want one set of "how we code" instructions, all three can do it.

The interesting difference is composition. Claude Code merges global and project skills automatically — both apply, and if descriptions match, both load. Cursor and Windsurf will load global rules and project rules together when both are configured. None of them has a clean override model ("this project rule replaces the global rule on the same topic"), which is something to watch out for if your global and project guidance contradict.

Discovery model

This is the biggest philosophical split. Claude Code reads descriptions and decides what to load per turn. Cursor and Windsurf load everything that's configured to be on, every turn. The Claude Code model scales further — you can install hundreds of skills without paying a per-turn token tax — but requires more discipline when writing skill descriptions. The Cursor/Windsurf model is dead simple to reason about: what's in the file is what the agent sees.

Multi-rule support

Claude Code is multi-rule by design. Cursor's classic .cursorrules is single-file, but the newer .cursor/rules/ directory closes the gap. Windsurf likewise supports both a single file and a directory of rules. If you want to maintain ten focused rule documents instead of one 3,000-line file, all three now let you.

Packaging and distribution

Claude Code skills package naturally as Git repos. A skill is just a directory with a SKILL.md — you can publish it on GitHub, clone it into ~/.claude/skills/, and you're done. This is why the SKILL.md ecosystem has grown so quickly: the unit of distribution is well-defined and copy-paste-free.

Cursor rules historically distribute as snippets — you find a .cursorrules file you like on awesome-cursorrules, copy its contents into yours, and merge by hand. The newer .mdc rule files are more portable as standalone artifacts, but there's no installed-but-inactive concept the way there is with Claude Code.

Windsurf rules are in a similar state — copy-paste distribution, growing ecosystem of community-shared rule files, no first-class "install" model.

Ecosystem

As of mid-2026, ClaudSkills indexes tens of thousands of public SKILL.md files. The awesome-cursorrules collections cover hundreds of starter rule sets. Windsurf's ecosystem is smaller but growing fast, particularly among teams that prefer the Cascade workflow.

Migrating between formats

The good news: these formats are close enough that conversion is largely mechanical. Here's a working .cursorrules:

# Database access

Never query the database from a React component. All DB calls go through server actions in app/_actions/ or route handlers in app/api/.

We use Drizzle ORM, not Prisma. Schemas live in src/db/schema/.

Migrations: pnpm db:generate to create, pnpm db:migrate to apply. Never edit the SQL output manually.

To turn that into a SKILL.md, wrap it with frontmatter and write a description that captures the trigger:

---
name: db-access-conventions
description: Use when reading from or writing to the database, designing schemas, or creating Drizzle migrations. Covers where DB calls are allowed, the Drizzle ORM choice, and migration commands.
---

# Database access

Never query the database from a React component. All DB calls go through server actions in app/_actions/ or route handlers in app/api/.

We use Drizzle ORM, not Prisma. Schemas live in src/db/schema/.

Migrations: pnpm db:generate to create, pnpm db:migrate to apply. Never edit the SQL output manually.

Save to .claude/skills/db-access-conventions/SKILL.md. Done. The body is identical; the only work is writing the description. A good description names the situations where the skill applies in the language the user is likely to use — that's what Claude matches against.

Going the other direction (SKILL.md → .cursorrules) is even easier. Strip the frontmatter, paste the body into .cursorrules. If you have multiple skills, concatenate the bodies with ## section headers between them. The catch: you lose Claude Code's intent-routing. Every skill body now loads on every Cursor turn, so your token bill grows and Cursor may attend to less-relevant guidance.

Two patterns to handle this:

  1. Split into Cursor's project rules directory. If you have, say, five SKILL.md files in .claude/skills/, mirror them as five .cursor/rules/<name>.mdc files with appropriate globs. You get per-file scoping at the cost of glob-based rather than intent-based matching.
  2. Keep only the universal guidance in .cursorrules. The stuff that applies to every file (conventions, stack choice, naming) goes in the always-on file. Specialised guidance stays in scoped .mdc rules or, if your team has both editors in play, in SKILL.md files for the Claude Code users.

For Windsurf, the migration mechanics are identical to Cursor — same flat text, same trade-off about always-on loading. Many teams just maintain a single rules file and let both Cursor and Windsurf read it via a symlink, since the contents work fine in both.

Picking the right model for your team

Tool choice is rarely a pure technical decision — it follows whichever editor your team has standardised on. But if you have a say, here's how the models differentiate.

Choose Claude Code's SKILL.md model when…

Choose Cursor's .cursorrules model when…

Choose Windsurf's model when…

For teams that span multiple editors (very common in 2026 — most orgs have a mix), the pragmatic answer is to support all three. The next section covers how that's playing out.

The interoperability layer

A growing pattern in open-source projects is shipping all three rule formats in the same repo. You'll find repos with a .claude/skills/ directory, a root .cursorrules, and a root .windsurfrules, all describing the same conventions in formats each tool can read natively. This costs a little duplication but lets every contributor use their preferred editor without losing the project's guidance.

There are a few approaches to managing the duplication:

  1. Source-of-truth markdown + exporters. Keep a single canonical file (often docs/conventions.md) and a small script that generates .cursorrules, .windsurfrules, and one or more SKILL.md files from it. Run the exporter on pre-commit. This is the cleanest model but requires up-front tooling.
  2. Symlinks. If your .cursorrules and .windsurfrules are byte-identical (very common), symlink one to the other. Some teams even symlink a SKILL.md body into .cursorrules with a small header, accepting the slight awkwardness for the convenience of single-source maintenance.
  3. Just maintain all three. Honest about the duplication, accept the drift risk, do periodic sync passes. Works for small teams with simple rules.

A handful of meta-tools have appeared that read multiple formats and translate between them. None has emerged as a dominant standard yet — most teams roll their own exporter when they need one.

The deeper trend worth watching: the formats are converging. Cursor's .cursor/rules/*.mdc looks structurally similar to .claude/skills/*/SKILL.md. Windsurf's directory-of-rules pattern is the same shape. Claude Code's frontmatter conventions are influencing how others structure their files. In two years it would not surprise me to see a shared community convention — call it RULE.md or whatever — that all three (and Cline, Roo Code, Aider, and whatever comes next) read natively.

Until then, the practical advice is: pick the model that fits your dominant editor, write the rules to be self-contained, and if your team is mixed, lean on the exporter pattern. Don't let the choice of rules format determine your editor — these mechanisms are close enough cousins that switching is a weekend of work, not a quarter of migration.

If you're building skills you intend to publish, start with SKILL.md. The format is the most portable (frontmatter + body is straightforward to translate into the other formats), and the auto-discovery model gives you the highest leverage as your library grows. The skills you see in the ClaudSkills category index were almost all written this way first, then ported to other formats by users who wanted them in Cursor or Windsurf.

Frequently asked questions

Can I use SKILL.md, .cursorrules, and .windsurfrules in the same repo?
Yes, and you should if your team is mixed. Each tool only reads its own file format and ignores the others. The trick is keeping them in sync — write the SKILL.md first (it's the most structured), then derive a leaner .cursorrules / .windsurfrules from it. A shared source-of-truth markdown file with per-tool exporters works well at scale.
Does Cursor's .cursorrules support multiple files?
The classic .cursorrules is a single root-level file. Cursor has added a newer .cursor/rules/ directory pattern (often called 'project rules') where you can have multiple .mdc files with frontmatter that scopes each rule to specific globs. This narrows the gap with Claude Code skills but still loads matching rules eagerly rather than on intent.
Will Claude Code load every SKILL.md in ~/.claude/skills/?
Only the skill descriptions are scanned at startup. Bodies load when Claude judges a skill relevant to the current request based on its description. So you can have hundreds of skills installed without paying a token cost for any specific conversation — the description-as-trigger pattern is the whole point.
Do .cursorrules count against my token budget?
Yes — every Cursor request prepends the full .cursorrules file to your system prompt. A 2,000-line .cursorrules sent on every keystroke completion adds real latency and cost. This is why disciplined Cursor teams keep their rules tight and move long-tail guidance into Cursor's newer scoped project rules directory.
Can I version-control SKILL.md files with the project they apply to?
Absolutely. Drop them in <code>.claude/skills/</code> at the repo root and commit. Anyone who clones the repo and opens Claude Code in that directory gets the project-scoped skills automatically alongside their global ones from <code>~/.claude/skills/</code>.
Which tool has the largest public ecosystem of shareable rules?
Cursor had a head start and the awesome-cursorrules lists are substantial. Claude Code's SKILL.md ecosystem has grown faster in 2026 because the format is more portable and the auto-discovery model encourages packaging skills as standalone repos. Windsurf's ecosystem is smaller but growing among teams that prefer its Cascade workflow.
What about Cline, Roo Code, Aider, and the other coding agents?
Cline uses 'Custom Instructions' configured in its VSCode settings — a single text blob, similar in spirit to .cursorrules. Aider has a CONVENTIONS.md pattern. Roo Code forked Cline and inherits its model. None of them currently match Claude Code's auto-discovery semantics, but several are converging on directory-of-markdown patterns.

Found a bug or want a topic covered? Email [email protected] or open an issue via GitHub.