AgentSkills.site

Cursor Skills vs Rules

The 10-second decision test, the official /migrate-to-skills conversion matrix, and deep architectural comparison: when to write a .cursor/rules/*.mdc rule and when to write a SKILL.md skill.

Published

Updated

AgentSkills.site editorial

The 10-second decision test: constraint or procedure?

If you are deciding whether to write a Cursor rule or a Cursor skill, use this fundamental distinction:

Is it a standing constraint or an on-demand procedure?
├── Standing constraint, code style, or invariant  →  Write a RULE (.cursor/rules/*.mdc)
│   (Always active or injected automatically when editing matching files)
│
└── Multi-step workflow, task, or procedure        →  Write a SKILL (SKILL.md)
    (Loaded on demand when relevant, file-scoped via paths, or triggered via /)
  • Write a Rule when you need standing guidance that Cursor must adhere to continuously (e.g., "Always use TypeScript strict mode", "Follow functional React conventions in components/**", "Never use lodash").
  • Write a Skill when you need a repeatable procedure that should only execute when relevant (e.g., "Review database migrations", "Deploy to staging", "Generate API client fixtures", "Audit accessibility").

Quick triage: rule or skill for your situation?

What you want Cursor to do Recommended mechanism Configuration Why this is the right choice
Always format code using tabs and specific import order Rule .cursor/rules/*.mdc (alwaysApply: true) Standing constraint. Must be injected into every prompt pass.
Enforce architectural boundaries (e.g. monorepo structure) Rule or AGENTS.md AGENTS.md or alwaysApply: true Repository-wide invariants belong in standing rules.
Enforce Next.js App Router conventions in .tsx files Rule .cursor/rules/*.mdc (globs: app/**/*.tsx) Deterministic file match; rule text injects directly when touching those files.
Audit database migrations for locking tables & rollbacks Skill SKILL.md (paths: db/migrations/**) Multi-step procedure. paths scopes eligibility without bloating general prompt context.
Run an interactive PR review or bug audit Skill SKILL.md (or built-in /review) On-demand procedure with detailed instructions and multi-agent coordination.
Deploy to production only when explicitly requested Skill SKILL.md (disable-model-invocation: true) Deterministic slash command. Agent will never trigger it autonomously.
Share the procedure across multiple AI agents Skill Cross-agent directories (e.g. .agents/skills/ or .claude/skills/) Portable open SKILL.md standard. .cursor/rules/*.mdc is proprietary to Cursor.

Architectural comparison: rules vs skills

Feature Cursor Rule (.cursor/rules/*.mdc) Cursor Skill (SKILL.md)
Primary purpose Short standing guidelines, constraints, and invariants Modular, repeatable multi-step procedures
File locations .cursor/rules/*.mdc or repository root AGENTS.md 8 scan directories (e.g., .cursor/skills/, .agents/skills/, ~/.claude/skills/)
File format Markdown with Cursor-specific YAML frontmatter (.mdc) Markdown with standard YAML frontmatter (SKILL.md)
Trigger options Always on (alwaysApply: true), file match (globs), prompt match ("Apply Intelligently"), or manual @-mention Prompt relevance (Semantic), file match (paths), or manual slash command (/skill-name)
Context footprint Injected directly into active prompt context when matched Summary indexed in catalog; full body and resources load only when executed
Bundled resources None (Single file only) Can bundle scripts/, references/, and assets/
Portability Cursor-proprietary format (.mdc) Base SKILL.md format is portable across agents; runtime features (subagents, browser, paths) remain tool-specific
Precedence rules Officially documented: Team Rules → Project Rules → User Rules Undocumented by Cursor for rules-vs-skills conflicts

Cursor's own documentation neatly summarizes the boundary: use rules for "short coding guidelines and constraints"; use skills for a "detailed, repeatable process."


What /migrate-to-skills tells us about Cursor's architecture

Cursor ships a built-in skill called /migrate-to-skills. To automate conversions, Cursor engineers defined mechanical criteria for what belongs in each system.

From Cursor's official documentation:

Dynamic rules: Rules that use the "Apply Intelligently" configuration—rules with alwaysApply: false (or undefined) and no globs patterns defined. These are converted to standard skills.
Slash commands: Both user-level and workspace-level commands are converted to skills with disable-model-invocation: true.

The official conversion matrix

Original configuration Frontmatter attributes /migrate-to-skills verdict Architectural reason
Always Apply Rule alwaysApply: true Stays a rule Standing constraint that must always be present.
File-Scoped Rule globs: "pattern" Stays a rule Deterministic constraint for specific file types.
Dynamic Rule ("Apply Intelligently") alwaysApply: false (or unset), no globs Converts to Skill Semantic relevance matching belongs in skills on-demand loading.
Manual Rule @-mention only Stays a rule On-demand reference document invoked manually.
Slash Command Legacy command Converts to Skill (disable-model-invocation: true) Commands are unified under the skills architecture with autonomous invocation disabled.

The underlying design principle is clear: deterministic triggers (always, file glob, or explicit @ reference) belong in rules. Whenever inclusion requires semantic judgement based on what the user is doing, the instruction belongs in a skill.


paths vs globs: the critical difference

Both Cursor rules and skills support file-matching patterns, but they behave very differently:

# In a rule (.cursor/rules/api-routes.mdc):
globs: "src/api/**/*.ts"
# Behavior: Injects the entire rule text directly into the system prompt 
# whenever a matching file is opened or edited.

# In a skill (.cursor/skills/audit-api/SKILL.md):
paths: "src/api/**/*.ts"
# Behavior: Marks the skill as ELIGIBLE for execution when matching files 
# are touched, but loads the skill instructions only if the model decides to run it.
  • Rule globs = Direct Prompt Injection: Use globs on a rule for short, immediate instructions (e.g., "In API routes, always use the Result<T, E> pattern").
  • Skill paths = Scoped Eligibility: Use paths on a skill for elaborate workflows that have executable scripts or reference documentation (e.g., a 200-line API contract testing checklist).

What Cursor does not document: two critical myths

Two common claims about rules and skills circulate in community discussions that are not backed by official documentation:

Myth 1: "Rules always take precedence over skills in conflicts"

Cursor documents a strict precedence order for rules: Team Rules → Project Rules → User Rules. However, Cursor publishes no documented precedence order between a rule and a skill.

If an always-on rule states "Never run integration tests locally" and a skill procedure instructs "Run integration tests before pushing", the behavior is non-deterministic. Do not rely on unverified precedence: resolve conflicting guidance in your configuration directly.

Myth 2: "Moving rules to skills saves a known amount of context tokens"

Cursor states that skills "load resources on demand, keeping context usage efficient," but does not publish a numeric context budget.

In contrast, Codex caps its skill catalog index at 2% of context or 8,000 characters, and OpenClaw documents ~97 characters per skill. While migrating large procedural rules to skills is directionally best practice, Cursor publishes no exact token count.


How to migrate rules to skills in practice

If your workspace has accumulated dynamic rules or legacy slash commands:

  1. Run the migration skill: In Cursor Agent chat, type:
    /migrate-to-skills
    
  2. Review the proposed conversion: Cursor scans .cursor/rules/ and identifies dynamic rules and slash commands.
  3. Audit the output:
    • Verify that the resulting folder names in .cursor/skills/<name> match the name: field in each generated SKILL.md.
    • Watch for false conversions: if a rule was configured as "Apply Intelligently" but was actually meant to be an invariant across your whole codebase, reconfigure it as alwaysApply: true or move it to AGENTS.md.

Caveats

  • We have not run Cursor or /migrate-to-skills. The conversion criteria and frontmatter attributes are verified directly from Cursor's official documentation.
  • The claim that rules override skills in conflicts is undocumented by Cursor and is not treated as fact here.
  • Slash command unification with disable-model-invocation: true aligns with similar architectural changes in Claude Code and OpenClaw.

Sources