packages/upgrade/README.md
</picture>
Changelog · Report a Bug · Request a Feature · Get help
</div>A CLI that detects your installed Clerk SDK, upgrades packages to the next major release, runs codemods, and scans your codebase for breaking changes.
>=20.9.0Run the CLI from the root of the project you want to upgrade:
# with pnpm
pnpm dlx @clerk/upgrade
# with npm
npx @clerk/upgrade
# if installed locally
pnpm clerk-upgrade
Fill out the prompts and the CLI will:
--sdk)@clerk/clerk-react → @clerk/react)--sdk — SDK to upgrade (e.g., nextjs, react, expo); required in non-interactive runs if detection fails--dir — directory to scan (default: current working directory)--glob — glob of files for codemods (default: **/*.(js|jsx|ts|tsx|mjs|cjs))--ignore — extra globs to ignore during scans (repeatable)--release — target release (e.g., core-3); otherwise auto-selected from installed versions--skip-upgrade — skip installing/updating packages--skip-codemods — skip codemod execution--dry-run — show what would change without writing or installingcore-3: upgrades Next.js 6 → 7, React 5 → 7, Expo 2 → 3, React Router 2 → 3, TanStack React Start 0 → 1, Astro 2 → 3, Nuxt 2 → 3, Vue 2 → 3; includes package renames for React/ExpoThe CLI selects the appropriate release automatically based on the installed major version, or you can pin a release with --release (currently core-3).
Scans rely on regular expressions, so some patterns (unusual imports, bound methods, indirect calls) can be missed. Codemods cover common upgrades, but you should still review the report, run your test suite, and verify the app before deploying.
The main thing that this tool will miss is cases where unusual import patterns are used in your codebase. As an example, if Clerk made a breaking change to the getAuth function exported from @clerk/nextjs, @clerk/upgrade would likely look for something like import { getAuth } from "@clerk/nextjs" in order to detect whether you need to make some changes. If you were using your imports like import * as ClerkNext from "@clerk/nextjs", you could use getAuth without it detecting it with its matcher.
It will also be very likely to miss if you bind a method on an object to a separate variable and call it from there, or pass a bound method through a function param. For example, something like this:
const updateUser = user.update.bind(user);
updateUser({ username: 'foo' });
Overall, there's a very good chance that this tool catches everything, but it's not a guarantee. Make sure that you also test your app before deploying, and that you have good E2E test coverage.
You can get in touch with us in any of the following ways:
We're open to all community contributions! If you'd like to contribute in any way, please read our contribution guidelines and code of conduct.
@clerk/upgrade follows good practices of security, but 100% security cannot be assured.
@clerk/upgrade is provided "as is" without any warranty. Use at your own risk.
For more information and to report security issues, please refer to our security documentation.
This project is licensed under the MIT license.
See LICENSE for more information.