packages/migrate/README.md
Automates and reports the breaking changes between major versions of Ionic Framework. It scans your app, applies the changes it can make safely, and prints a checklist of the ones you need to do by hand, each with a file and line and a link to the docs.
It handles Angular, React, and Vue (and vanilla) from one command. New breaking changes and future majors are added as data, not new tooling.
Run it from the root of your app:
npx @ionic/migrate
Commit first. The tool edits files in place and won't write to a dirty working tree, so git is your undo. Then review the diff and the checklist it prints.
--dry-run Report what would change without writing anything
--check Report only. Exit non-zero if any migration applies (for CI)
--experimental Include experimental migrations
--force Write even if the working tree is dirty or not a git repo
--no-format Skip running the project's Prettier over changed files
--no-install Skip reinstalling dependencies after the version bump
--from <major> Override the detected source major version
--to <major> Override the target major version
-h, --help Show this help
Every breaking change is one of three kinds:
--experimental. A report-only migration covers
the same change by default.Each major upgrade has its own page, listing every change the tool covers, whether it is auto-fixed, report-only, or experimental, and the changes left for you to make by hand:
package.json.--no-format to skip it.node_modules matches the bumped package.json. Pass --no-install to skip
it, then reinstall yourself before starting the app.Transforms use ts-morph to locate nodes for TypeScript and TSX, and a small
quote-aware scanner for HTML and Vue templates, so it doesn't touch string
literals, comments, or unrelated code.
These hold for every major. What a given upgrade can't reach is on its own page
under docs/.
@ionic/* bump has landed..ts and .tsx are loaded into ts-morph, so .js/.jsx files and
Angular inline templates (a template: string in a decorator) get the
text-scan migrations but not the AST-based ones.tsconfig.json is read. The type checker gets a fixed configuration, so a
paths alias doesn't resolve, and a migration reading types treats what it
can't reach as unknown rather than as nothing to report..css and .scss files. Styles inlined in a
component decorator's styles array aren't read.Add a migration by dropping a file under src/migrations/v<major>/ that exports
a Migration (see src/types.ts) and registering it in
src/migrations/index.ts. Give it a detect() and, when the change is safe to
automate, a fix(), plus fromMajor/toMajor for version scoping and a
fixture-backed test. The engine handles selection, ordering, git safety,
formatting, and reporting.
Then add a row to that major's page under docs/, creating
docs/v<major>.md if it's the first migration for a new one. That page is what
tells someone whether an upgrade is covered, so it's part of the migration, not
an afterthought.
npm test # Vitest
npm run lint # tsc --noEmit
npm run build # emit dist/