Upgrading
catalyst upgrade brings an existing Catalyst project forward to a newer release. It downloads your project’s current base version and the target version, then applies a 3-way merge between that base, your local changes, and the target. Changes that don’t conflict with your customizations are staged automatically; anything that does conflict is left as standard Git conflict markers for you to resolve.
Prerequisites
Before running the upgrade:
- A clean Git working tree. The merge writes in place, so any uncommitted changes in your project would be indistinguishable from the upgrade itself. Commit or stash them first.
@bigcommerce/catalystinstalled as a dependency. This is the CLI package that provides theupgradecommand. Projects scaffolded with a recent version ofcatalyst createalready have it. If yours doesn’t — most commonly legacy monorepo-structure projects created before the CLI existed — install it first.- A
catalyst.reffield inpackage.json. This tells the CLI which version your project is currently on, so it knows what to diff against. If it’s missing, the CLI infers a base version from your package name and version and asks you to confirm before continuing (skip the prompt with--yes). If the inferred base is wrong, pass--from <ref>to set it explicitly — for example,--from @bigcommerce/catalyst-core@1.6.0.
Run the upgrade
Run the command from inside your Catalyst project:
Run the upgrade command
pnpm exec catalyst upgrade works the same way. With no arguments, this upgrades to the latest tag in the same package family your project is already on (for example, @bigcommerce/catalyst-core or @bigcommerce/catalyst-makeswift). Pass a specific version to target it instead:
To move to a different integration family — for example, adding Makeswift to a project that started as core-only — pass the full tag with --ref:
Preview before applying (optional)
Run with --dry-run first to see the diff between your base version and the target without changing any files:
This is worth doing on any upgrade where you’ve made substantial customizations, since it gives you a sense of the conflict surface before committing to the merge.
Resolve conflicts
Without --dry-run, the CLI merges the target version into your project and stages every file that merged cleanly. Files with conflicts are left as unmerged entries with standard <<<<<<< ours / ======= / >>>>>>> theirs markers, the same as any Git merge — most editors’ merge tooling picks them up automatically. The upgrade never aborts partway through, even if every file conflicts.
Recommended upgrade cadence
Upgrade one minor version at a time rather than jumping straight to the latest release, especially on a project with significant customizations. The merge diffs your base version directly against the target, so a larger version gap means a larger diff and more surface area for conflicts.
Low-confidence base warning
If your project’s package.json has no catalyst.ref field and you don’t pass --from, the CLI has to infer your base version. It then checks that guess by measuring how many of the inferred base version’s files still match your project unmodified. When fewer than 50% match, it warns that it has low confidence in the inferred base, because the guess is probably wrong (for example, the version field was bumped without actually upgrading). If the merge result looks off, re-run the upgrade with --from <version> to set the correct base explicitly.
Dependency versions
catalyst upgrade keeps your @bigcommerce/catalyst* dependencies (including @bigcommerce/catalyst-client) current as part of the same merge that updates everything else. As long as your project pins one of these packages to an ordinary semver range, a version bump shipped in the target release is applied automatically — or flagged as a conflict if you’d deliberately pinned that dependency to something else. There’s no separate step or command for this; it’s handled the same way as any other package.json change.
Update the CLI itself
The CLI that runs the upgrade can’t upgrade itself through the same merge, so it checks the npm registry directly (best-effort — a registry hiccup never fails the upgrade). If a newer version is available, you’ll see an advisory at the end of the run:
Run the suggested command, then continue with your next upgrade as usual.
Legacy monorepo-structure projects
Catalyst historically shipped as a monorepo clone, with core/ nested under a repo root alongside sibling packages/ directories. Newer projects are flat, with the same contents at the repo root. catalyst upgrade detects either layout automatically by locating the package.json that carries a catalyst field, so upgrading a monorepo-structure project doesn’t require restructuring it first.
The one thing a monorepo-structure project needs before its first upgrade is the CLI itself — these projects predate @bigcommerce/catalyst existing as a package, so it was never installed as a dependency. Add it before running upgrade:
After that, catalyst upgrade works the same as it does on a flat project, apart from the workspace dependency prompt described below.
Dependencies on the workspace protocol
Monorepo-structure projects often reference Catalyst packages with a workspace:^ specifier, which resolves to the local copy in packages/ rather than the published package. After the merge completes, the CLI lists these dependencies and offers to replace them with the published versions:
- Accepting (or passing
--yes) switches the dependency to the published version from your target release, so future upgrades keep it current automatically. - Declining keeps the
workspace:^specifier and your localpackages/copy.catalyst upgradewon’t update that dependency on future upgrades unless you accept the prompt then.
The prompt runs only when the merge is actually applied, not with --dry-run.
Next steps
- Catalyst CLI reference for the full flag list.
- Versioning for how Catalyst branches, tags, and releases are structured.