Skip to content

feat(migrate): rework migrations and initial sveltekit-3 migration#1138

Draft
manuel3108 wants to merge 89 commits into
mainfrom
feat/sv-migrate
Draft

feat(migrate): rework migrations and initial sveltekit-3 migration#1138
manuel3108 wants to merge 89 commits into
mainfrom
feat/sv-migrate

Conversation

@manuel3108

@manuel3108 manuel3108 commented Jun 13, 2026

Copy link
Copy Markdown
Member

Relates #1111
Closes #1124

Description

This PR lays the groundwork for making sv migrate the new home for Svelte migrations.

It does a few things:

  • bumps svelte-migrate to a new major version so it can be deprecated in favor of sv migrate
  • rewrites the migration system to re-use the tooling and utilities we have built for sv add over the last two years
  • removes previous migrations from the source code
  • keeps previous migrations available to users as legacy migrations by delegating to npx svelte-migrate@1
  • introduces a new migration system that is closely aligned with the existing sv add architecture

Migration system

The new system is built around two concepts: migrations and migration tasks.

A migration is the top-level wrapper. It is similar to what we had before and will usually be added alongside a new version release, though not necessarily only for major releases.

A migration task is the actual execution unit responsible for applying part of a migration. Larger migrations can be split into multiple tasks. For example, sveltekit-3 currently consists of separate tasks for package.json, svelte.config.js, and environment variable changes.

Tasks can be required or optional. Optional tasks can be selected or deselected by the user, which has a few important benefits:

  • users can migrate step by step
  • users can split migration changes into multiple commits more easily
  • each task can represent a clear testing surface

Each task receives almost the same parameters as an addon, with only minor differences. This allows migrations to re-use addon functionality directly. For example, the sveltekit-3 migration calls the experimental addon to update package.json and the relevant peer dependencies.

Multi-file migrations

To support migrations that need to edit multiple files, this PR introduces sv.files in addition to sv.file:

sv.files(
	{
		// glob expression evaluated with fs.globSync by sv
		include: '**/*.svelte',

		// early string-based content filter to avoid running expensive edit functions for unrelated files
		where: (content) => content.includes('$env/')
	},
	transforms.svelteScript({ language }, ({ ast }) => {
		return changeImports(ast.instance.content);
	})
);

Migrating

# basics (will prompt everything that is not explicitely provided)
pnpx sv migrate sveltekit-3

# with path
pnpx sv migrate sveltekit-3 --cwd ../your-work-dir 

# only required tasks (like package.json)
pnpx sv migrate sveltekit-3 --tasks required

# only required and selected optional task
pnpx sv migrate sveltekit-3 --tasks env-vars

# no prompt workflow
pnpx sv migrate sveltekit-3 --cwd ../your-work-dir --tasks all --confirm --install pnpm

Pending work

  • Decide whether we want additional verification steps before running migrations
    • lint check We decided against this for now
    • svelte-check We decided against this for now
  • Add docs and readmes
    • sv.files
    • sv migrate
  • Implement the env-vars migration
  • Fix and bump esrap
    • It currently generates a lot of new lines where the previous content did not have them.
    • This may be difficult and could potentially require a major bump for esrap.
    • This is not possible in esrap as it takes the ast as an argument and is unaware of the input. Therefore implemented based on a text diff library that does the job pretty good preserveOriginalNewlines
  • Add tests for migrations
    • This should be fairly straightforward once a few migration testing helpers are in place.
  • Add more command-line arguments
    • Currently not all prompts can be skipped through CLI arguments.
  • allow users to pass a glob expression / directory / file and only migrate this one
  • migration for $app/environment to $app/env
  • check migration for app-state (legacy) and see if we can use that one or if we should rewrite it Should be fine, migration was published over 1.5 years ago
  • expose an api for migrations, so that we can use it from the playground, vs code extension and whatever will be implemented at a later point

Checklist

  • Update snapshots (if applicable)
  • Add a changeset (if applicable)
  • Allow maintainers to edit this PR
  • I care about what I'm doing, no matter the tool I use (Notepad, Sublime, VSCode, AI...)

@changeset-bot

changeset-bot Bot commented Jun 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 85c1e75

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
sv Minor
@sveltejs/sv-utils Patch
svelte-migrate Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

jycouet added 4 commits June 20, 2026 23:38
Merge the missing-package.json and missing-deps cases into one actionable
message (absolute path + --cwd/--help hints), and render migration setup
failures cleanly instead of dumping a stack trace.
….json

Migrations don't all need a svelte/kit project (legacy ones hand off to
svelte-migrate). Let each migration's setup declare its own needs; the
shared check now only ensures a package.json exists. sveltekit-3 keeps the
kit requirement with an actionable message.
Comment thread packages/sv/src/addons/experimental.ts
@manuel3108 manuel3108 changed the title wip: feat(migrate): rework migrations and initial sveltekit-3 migration feat(migrate): rework migrations and initial sveltekit-3 migration Jun 21, 2026
Comment thread packages/sv/src/migrate/migrations/sveltekit-3/tasks/svelte-config.ts Outdated
jycouet and others added 6 commits June 26, 2026 05:24
* feat: migration-task comment management

- @migration-task comments now work in .svelte files (insert real Comment
  nodes into the fragment, since the Svelte printer ignores the JS Comments
  registry); fixes the env task silently dropping them.
- single addMigrationTask(message, target): { comments, node } for JS/TS,
  { fragment, anchor? } for .svelte.
- split migrate/index.ts into index.ts (framework) + migration-task.ts.

* fmt
* feat(migrate): defer formatting to project format script

Migrate now runs the nearest `format`/`fmt` package.json script (walking up
to the workspace root) before falling back to prettier on modified files.
`formatFiles` takes a `strategy` param; create/add keep the files-only path.

* fix: import order in formatFiles
* feat: migration-task comment management

- @migration-task comments now work in .svelte files (insert real Comment
  nodes into the fragment, since the Svelte printer ignores the JS Comments
  registry); fixes the env task silently dropping them.
- single addMigrationTask(message, target): { comments, node } for JS/TS,
  { fragment, anchor? } for .svelte.
- split migrate/index.ts into index.ts (framework) + migration-task.ts.

* fmt

* feat: reborn app-state migration (AST-based)

Rebuild `$app/stores` -> `$app/state` as a proper AST task instead of the
regex legacy shell-out. Runnable standalone (`sv migrate app-state`) and
required inside the sveltekit-3 migration.

Bug fixes over the legacy version:
- truthy `$navigating` (e.g. {#if $navigating}) -> `navigating.to`
- bail cases (`$:`, `derived(store)`, `getStores()`) now leave a @migration-task instead of silently skipping
- drop spurious TODO when `.to` is already accessed

---------

Co-authored-by: Manuel <30698007+manuel3108@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sv migrate

2 participants