---
name: svelte5-migration-analyst
description: Analyze a React/Next/Vue/Nuxt/Angular/Svelte-4 project and report what migrating to Svelte 5 + SvelteKit would actually buy — measured bundle reduction, dependencies eliminated by native Svelte APIs, performance impact — then produce a phased migration roadmap with line-by-line framework translation. Use when asked to evaluate, estimate, plan, or justify a Svelte migration, to compare a current stack against Svelte, to translate Angular/React/Vue patterns into Svelte 5, or to find which dependencies Svelte's built-ins would replace.
---

# Svelte 5 migration analyst

Two deliverables: an evidence-based assessment, and — only if the assessment supports it — a
migration roadmap.

The failure mode this skill exists to prevent is a confident report full of invented numbers.
Framework migrations get sold on "3× faster, 60% smaller" figures nobody measured, and the team
finds out in month two. Measure what can be measured, bound what cannot, and be willing to
conclude *don't migrate*.

Every rule below is here because it was violated by an earlier version of this skill and caught
by a real migration. `references/field-notes.md` has the receipts.

## Ground rules

1. **Never state a number you did not measure or bound.** Tag every figure `[measured]`,
   `[bounded]`, or `[projected]` with its basis. See `references/measurement.md`.
2. **Write the predictions down before the work starts, and score them after.** A forecast nobody
   scores gets remembered as roughly right. Step 6 below is not optional.
3. **Check the deployment target before valuing bytes.** For Electron/Tauri/Capacitor the bundle
   is read from local disk and Lighthouse does not apply. See `references/desktop-apps.md`.
4. **"Removed from your source" ≠ "removed from the bundle."** A package the UI never imports
   arrives transitively and survives the rewrite. Both scripts check import sites now; say
   "no longer imported by UI code" unless you re-measured.
5. **A component library is rarely a net-zero swap.** Measured: 697 KB of Angular Material became
   72 KB of Svelte primitives, because most of it existed only to paper over the framework. Ask
   how much becomes plain markup before quoting the swap bucket.
6. **`node_modules` gets bigger.** SvelteKit ships a compiler and Vite toolchain as
   devDependencies (57 packages, 67 MB, **0 runtime dependencies**). Report the increase openly;
   the win is shipped bytes and production dependency surface.
7. **"Do not migrate" is a valid verdict.** If the bottleneck is a slow API, 4 MB of images, or a
   desktop app nobody waits on, say so first — not in a footnote.
8. **Write current Svelte 5, verified.** Svelte 4 idioms in Svelte 5 files compile fine and throw
   away the point of the migration.

## Setup: the official Svelte MCP server

**Check for `mcp__svelte__*` tools before starting.** Adding the server mid-session does not load
its tools, so the autofixer gate silently never runs — this happened on a real migration and every
component went unverified.

```bash
claude mcp add -t http -s user svelte https://mcp.svelte.dev/mcp
```

`list-sections`, `get-documentation`, `svelte-autofixer`, `playground-link`. Full workflow in
`references/mcp-workflow.md`. If it is unavailable, say so **in the report** and fall back to
`references/svelte5-idioms.md`.

## Workflow

### 1. Inventory

```bash
node scripts/analyze.mjs <project> --json --out migration/baseline/deps.json
```

Framework, **deployment target**, routes (declared, not directory-guessed), components tiered by
complexity, import sites per dependency, transitive closure delta, hazards, effort band.
Needs `node_modules` installed.

Read the `target` and `routes` fields first — they decide whether the rest of the report is even
the right report. One route and no server means SvelteKit is a Vite wrapper; say so.

### 2. Measure the bundle

```bash
npm run build && node scripts/attribute.mjs <project> --json --out migration/baseline/bundle.json
```

Emitted-span attribution from sourcemaps. No sourcemaps → enable them and rebuild, or report
totals only.

### 3. Baseline performance

Web target: Lighthouse on the top routes, median of 5+ runs.
Desktop target: parse+compile benchmark and a packaged-build comparison **with a control metric** —
see `references/desktop-apps.md`. Do not fabricate Lighthouse numbers for an app with no URL.

If the bottleneck is not framework overhead, that determines the verdict.

### 4. Read the code

Numbers describe shape, not tractability. Read the largest components, the state layer, the data
layer, and every hazard. Look for coupling to the source framework: RSC boundaries, DI graphs,
UI files importing Node builtins.

### 5. Write the assessment

Follow `references/report-template.md` → `migration/svelte5-assessment.md`. Verdict first.
Summarise in chat; do not paste the report.

### 6. Record predictions

```bash
node scripts/predict.mjs init --analysis migration/baseline/deps.json \
  --bundle migration/baseline/bundle.json --out migration/predictions.json
```

Review the generated ledger: delete anything you do not believe, and add the claims your report
makes that it could not infer. Every entry needs a metric and comparison, or an explicit `manual`
marker — never a claim that quietly disappears.

### 7. Approval gate on dependency decisions

Put the plan to the user before writing the roadmap. Use `AskUserQuestion` for the judgement
calls: component library strategy (check platform elements first), what replaces react-query,
experimental remote functions, contested swaps, and every unclassified package. Do not ask about
deleting `clsx`.

### 8. Roadmap

Only if the verdict supports it. Follow `references/migration-playbook.md`, adapted to this app.
Name real routes and files. Phase 1 is a go/no-go gate that replaces projections with measurements.

## During the migration

- **Translate with the reference for the source framework**: `references/translate-angular.md`,
  `translate-react.md`, `translate-vue.md`. These are line-by-line tables — API, template syntax,
  state, DI, routing, forms, component libraries — with the naive-but-wrong translations called out.
- **Every component through `svelte-autofixer`** in a loop until clean. Per component, not per
  phase — a systematic error caught on file #1 saves rewriting files #2–#40.
- **`get-documentation` before using any API you have not touched this session.**
- `npx sv migrate svelte-5` / `app-state` / `self-closing-tags` handle syntax only; they do not
  reshape state, and that reshaping is the actual work.
- **Re-score predictions at every phase gate:**
  ```bash
  node scripts/predict.mjs score --predictions migration/predictions.json \
    --analysis <new deps.json> --bundle <new bundle.json> --md
  ```
  Paste the scorecard into the phase results document. Report misses in both directions — a
  prediction wrong in the migration's favour still misled whoever funded it. An unexercised
  prediction is **unresolved**, not confirmed.
- **Read `references/field-notes.md` before Phase 4.** It covers the gap between "tests pass" and
  "port is done": silent CSS failure, audit lenses and their blind spots, defects concentrating in
  failure paths, benchmark controls.

## Reference files

| File | Read when |
|---|---|
| `references/measurement.md` | Producing any number |
| `references/svelte5-idioms.md` | Writing or reviewing Svelte 5 |
| `references/translate-angular.md` | Source is Angular (validated against a complete port) |
| `references/translate-react.md` | Source is React or Next.js |
| `references/translate-vue.md` | Source is Vue or Nuxt |
| `references/desktop-apps.md` | Target is Electron, Tauri, Capacitor |
| `references/field-notes.md` | Before Phase 4, and when a phase looks suspiciously done |
| `references/mcp-workflow.md` | Wiring the Svelte MCP into the loop |
| `references/migration-playbook.md` | Building the roadmap |
| `references/report-template.md` | Structuring the assessment |
| `scripts/dep-map.json` | Adding or correcting a package classification |

Verified against svelte 5.56.8 / @sveltejs/kit 2.70.1 on 2026-07-29, and validated against a
complete 49-component Angular → Svelte 5 production port. Re-verify the moving parts — remote
functions are still experimental — before relying on them.
