knack
← all posts

The 30-Minute Cursor to Claude Code Migration (and the Step Everyone Skips)

A clean migration takes 30 minutes if your .cursorrules is in shape. Most guides stop at CLAUDE.md. The real payoff is step 3: promoting your repeated Cursor prompts into a SKILL.md.

A clean cursor to claude code migration takes 30 minutes if your .cursorrules file is in good shape and your repeated prompts already live in a snippets folder somewhere. It takes an afternoon if those patterns live in your head, scattered across six months of chat history with Cursor's Composer. The difference between the two is whether you do step 3.

Most guides on how to switch from cursor to claude code stop at step 2. Conductor's official walkthrough copies .cursorrules to CLAUDE.md, moves ~/.cursor/mcp.json to ~/.claude.json, and calls it done (Conductor docs). The 56kode post that's been making the rounds on r/ChatGPTCoding does the same thing and adds Plan Mode (56kode). Developers Digest gets one sentence closer to the real answer: "Save reusable prompts to ~/.claude/prompts/<name>.md. Create skills at ~/.claude/skills/<name>/SKILL.md with trigger phrases" (Developers Digest). Then they move on.

Step 3 is the whole point. Your .cursorrules file is the easy part. The hard part is the prompts you've been pasting into Cursor's chat for the last year. Those need a home, and that home is a SKILL.md.

Step 1: Move your .cursorrules into CLAUDE.md

If you have a .cursorrules at the root of your repo, you're 80% of the way through step 1. Claude Code reads ./CLAUDE.md automatically at session start. The Conductor migration script does the literal copy for you:

cp .cursorrules CLAUDE.md

If you're on the newer .cursor/rules/*.mdc layout, you need to strip YAML frontmatter from each file and concatenate. One-liner from the Conductor team:

for f in .cursor/rules/*.mdc; do
  sed '1{/^---$/!q;};1,/^---$/d' "$f" >> CLAUDE.md
done

A common assumption about how to switch from cursor to claude code is that the /init command will detect .cursorrules and convert it. It used to. Issue #1705 on the anthropics/claude-code repo tracked the bug where /init only saw the legacy .cursorrules file, not the .cursor/rules/ directory. It was closed as not planned. If you run /init today on a fresh Cursor project, expect it to find the flat file and miss the directory. Copy manually.

One quirk worth knowing. Claude Code's docs target under 200 lines per CLAUDE.md file. A lot of .cursorrules files I see are 800 lines of "always do X" / "never do Y" rules that have accumulated for a year. Delete half of it during the migration. The ones you want enforced are usually 30 to 60 lines.

Step 2: CLAUDE.md scopes and the @ import system

This is where the .cursorrules to claude.md migration stops being a cp command and starts being architecture. Claude Code reads CLAUDE.md from four scopes, in this load order:

  1. Managed (org-wide, IT-controlled) at /Library/Application Support/ClaudeCode/CLAUDE.md on macOS or C:\Program Files\ClaudeCode\CLAUDE.md on Windows
  2. User at ~/.claude/CLAUDE.md
  3. Project at ./CLAUDE.md or ./.claude/CLAUDE.md
  4. Local at ./CLAUDE.local.md (gitignored)

The Cursor mental model is one rules file per project. Claude Code's model is layered: your personal preferences live at the user scope, your team's conventions live at the project scope, and your machine-specific notes live in .local. The same machine can have a different CLAUDE.md per project plus user-level defaults that bleed through.

The @ import system is the other thing Cursor doesn't have. Inside any CLAUDE.md you can write:

See @README.md for the project overview.
Database conventions: @docs/db-conventions.md
Git workflow: @docs/git-instructions.md

Claude resolves up to 5 hops of imports at session start. This matters for cursor vs claude code migration because the Cursor pattern of "one massive rules file" becomes the Claude Code pattern of "thin CLAUDE.md that imports specialized docs." Long rules in one file get truncated and lose precedence. Decomposed imports stay coherent.

Carry your MCP servers over while you're here. Cursor stores them in ~/.cursor/mcp.json globally and .cursor/mcp.json per project. Claude Code reads ~/.claude.json globally and .mcp.json (no dot-cursor prefix) per project. The JSON schema is identical. Same mcpServers object, same env block. Don't commit secrets in .mcp.json; reference shell variables instead. Restart Claude Code after editing; both tools read MCP config at startup and ignore live changes.

Hooks are the third config to think about. Cursor doesn't have a direct equivalent. Claude Code's hooks live in .claude/settings.json and fire on events like PreToolUse, PostToolUse, SessionStart, and UserPromptSubmit (Claude Code settings docs). If you were faking hooks in Cursor by telling the model "always run pytest after editing test files," that's now a PostToolUse hook with a matcher on Edit and a command that runs your test runner. Stronger guarantee, no model in the loop.

Step 3: Promote your repeated prompts into a SKILL.md

Open your Cursor chat history. Count the times you've pasted some variant of "review this PR and check for missing tests, then suggest commits split logically by concern." Count the times you've typed "scaffold a new FastAPI endpoint following the pattern in routes/users.py with a pydantic request model, route handler, service-layer call, and integration test." If the answer is more than five, step 3 is mandatory.

Each of those is a SKILL.md.

A skill is a folder at ~/.claude/skills/<name>/ (user scope) or .claude/skills/<name>/ (project scope) containing a SKILL.md file. The format is two YAML fields plus markdown:

---
name: scaffold-fastapi-endpoint
description: Scaffolds a new FastAPI endpoint with request model,
  route handler, service-layer call, and an integration test. Use when
  the user asks to add an endpoint, create a route, or wire up a new
  POST/GET handler in a FastAPI app.
---

# Scaffold a FastAPI endpoint

Follow the pattern in `apps/api/knack_api/routes/users.py`.

## Steps

1. Add the pydantic request and response models in `routes/<name>.py`.
2. Implement the route handler with the standard auth dependency.
3. Add the business logic to `services/<name>.py`. Don't put DB calls
   in the route file.
4. Write an integration test in `tests/test_integration_<name>.py`
   that hits the real route via TestClient.
5. Register the router in `main.py` if it's new.

## Conventions

- All endpoints return Pydantic models, never raw dicts.
- 4xx errors raise `HTTPException`. 5xx errors raise domain exceptions
  and let the global handler convert them.
- Integration tests get a fresh SQLite DB per test via the
  `db_session` fixture.

Claude reads name and description at session start to decide whether to load the rest. The description is doing the actual work; write it like a search query you'd type if you were looking for this skill. "Use when the user asks to..." phrasings are the convention in the anthropics/skills repo and they make the trigger reliable.

The PR review case looks similar:

---
name: review-pr
description: Reviews a pull request for missing tests, unhandled edge
  cases, and commit hygiene. Use when the user says "review this PR",
  "look at my changes", or pastes a branch name and asks for feedback.
---

# Review a pull request

1. Run `git diff main...HEAD` to see all changes.
2. For each changed file, identify the public surface that needs a test.
3. Flag any function over 40 lines as a candidate for split.
4. Check that commits are atomic. Suggest a re-organization if they aren't.
5. Output a markdown summary with three sections: must-fix, nice-to-have,
   and lgtm.

Two skills in 15 minutes is roughly two hours of pasting eliminated over the next month. The arithmetic works fast.

This is the part of the cursor to claude code migration that nobody automates well, because the prompts live in your head. Knack is the tool I built for this specifically: it interviews you about the procedure (what triggers it, what files it touches, what the output looks like, what edge cases trip it up) and writes the SKILL.md folder for you. The trigger-phrase wording in the description is the hardest part to get right, and an interview catches the variants you'd miss writing it cold.

What doesn't transfer

Cursor's inline edit popup, the Cmd-K instant-edit, and the Composer file-selection pane have no Claude Code equivalent. Claude Code is a terminal agent. You give it a task, it edits files in batch, you review the diff after. The 56kode post calls this the shift from "coding to supervising" and that matches my experience. The first day feels slower because you're not making micro-edits in real time. By day three the throughput is higher because the agent does the boring scaffolding while you read the diff.

The Cursor tab-completion model also doesn't carry over. Claude Code isn't running in your editor's gutter. If you want completions, you keep VS Code or Cursor open for that and use Claude Code in the terminal alongside it. A lot of Cursor refugees end up with this two-pane setup for the first month.

What to do this week

Block 30 minutes today. Run cp .cursorrules CLAUDE.md, move MCP servers from ~/.cursor/mcp.json to ~/.claude.json, and trim CLAUDE.md to under 200 lines.

Block another 30 minutes Friday. Open your Cursor chat history, find the three prompts you've pasted most often, and write a SKILL.md for each. Put them in ~/.claude/skills/ if they're personal, .claude/skills/ if your team will use them. If you want the interview-driven version, Knack writes the SKILL.md folder from a 6-step conversation and handles the trigger-phrase wording.

Two weeks in, the test is simple. You open a new project and the chat history is empty. Do you reach for Cursor to retype the prompt, or do you reach for a skill name? If it's the second one, migrating from cursor to claude code worked. If it's the first, you stopped at step 2.