How the Astryx Upgrade Command Runs Version Migration Codemods

The astryx upgrade command automates version-to-version migrations for Astryx projects by detecting your installed core package version, collecting applicable codemod transforms for the version range, and executing them against your source tree.

The astryx upgrade command is the official CLI tool for migrating Astryx codebases between versions. According to the facebook/astryx source code, it orchestrates a three-step pipeline that handles everything from version detection to automated code transformation. This command eliminates manual refactoring when upgrading @astryxdesign/core by executing codemods—automated scripts that transform your source code to match new API patterns.

The Three-Step Upgrade Pipeline

When you execute astryx upgrade, the command implementation in packages/cli/src/commands/upgrade.mjs performs a standardized workflow:

  1. Detect the installed core package – The command reads the version of @astryxdesign/core (or legacy @xds/core) from node_modules to determine the target version.
  2. Run codemods – Using the version range --from <old-version> to the detected version, it loads transformation manifests from the registry and executes each codemod against your source tree.
  3. Refresh agent docs – After codemods finish, it regenerates AGENTS.md or CLAUDE.md files if they exist in your project.

Detailed Execution Flow

Option Parsing and Validation

The command accepts multiple flags to control the migration behavior. In packages/cli/src/commands/upgrade.mjs (lines 17–27), the CLI defines options including --from, --apply, --force, --codemod, --skip-codemod, --integration, --path, and --install-deps.

The --from flag is strictly validated using isValidSemver() from packages/cli/src/utils/semver.mjs. If you provide an invalid semver string, the command aborts immediately (lines 88–96).

Version Detection

Before running any transforms, detectInstalledTargetVersion() (lines 60–78) scans node_modules/@astryxdesign/core (falling back to @xds/core for legacy projects) for a package.json file and extracts the version field. This becomes the target version for the migration range.

Codemod Selection and Registry

The registry in packages/cli/src/codemods/registry.mjs stores per-version manifests containing available transforms. The function getTransformsBetween(from, to) (line 42) walks the version list and merges all transforms whose versions fall between your supplied --from version and the detected target version.

Each manifest entry contains {name, transform, meta, optional} properties. Optional codemods are skipped unless you explicitly request them via the --codemod flag.

Running Core Codemods

The runCodemods() function in packages/cli/src/codemods/runner.mjs (lines 71–134) handles the actual transformation:

  • Loads jscodeshift to parse and transform JavaScript/TypeScript files
  • Iterates over each version manifest
  • Reads source files from the --path directory
  • Applies transforms and validates output
  • Writes changes only when --apply is set (dry-run by default)

If you specify --integration, the command additionally discovers and executes integration-specific codemods via discoverIntegrationCodemods and runIntegrationCodemods (lines 45–48).

Post-Codemod Hooks and Documentation

After transformations complete, the command executes any postCodemod hooks defined in your Astryx configuration (lines 86–136). It then triggers installAgentDocs to regenerate AGENTS.md or CLAUDE.md files (lines 49–50), ensuring your documentation reflects updated component APIs.

Common Usage Examples

Preview Changes Without Writing Files

By default, the upgrade command runs in dry-run mode, showing what would change without modifying files:


# After installing the new @astryxdesign/core version

astryx upgrade --from 0.0.6

This reads the installed core version (e.g., 0.0.8), gathers all codemods from 0.0.6 → 0.0.8, and prints a preview to stdout.

Apply Migrations to Source Files

To actually write the transformed code back to disk:

astryx upgrade --from 0.0.6 --path ./src --apply

The --apply flag commits changes. Always run without --apply first to review the migration impact.

Run a Specific Codemod

To execute only one transform rather than the full version range:

astryx upgrade --from 0.0.6 --codemod rename-stack-element-to-as --apply

This targets only the rename-stack-element-to-as transform, useful when you need granular control over large migrations.

Skip Failing Codemods

If a specific codemod causes issues, exclude it while running others:

astryx upgrade --from 0.0.6 --skip-codemod rename-action-props --apply

The --skip-codemod flag accepts a comma-separated list of transform names to omit.

CI-Friendly Automation

For automated pipelines where interactive prompts are not available:

astryx upgrade --from 0.0.6 --install-deps --apply

The --install-deps flag automatically installs jscodeshift inside CI containers without requiring manual confirmation.

List Available Transforms

To see all registered codemods before running:

astryx upgrade --list

This prints a deduplicated list of every codemod registered by the core package and any loaded integrations.

Summary

  • astryx upgrade is the official CLI entry point for automated version migrations in the Astryx ecosystem.
  • The command reads your current @astryxdesign/core version from node_modules and calculates the transformation range from your --from parameter.
  • Codemods are selected from packages/cli/src/codemods/registry.mjs using getTransformsBetween() and executed via the runner in packages/cli/src/codemods/runner.mjs.
  • Dry-run mode is the default; you must pass --apply to write file changes.
  • The command supports granular control via --codemod, --skip-codemod, and --integration flags.
  • Post-migration, it automatically refreshes agent documentation (AGENTS.md, CLAUDE.md) to reflect API changes.

Frequently Asked Questions

What happens if I don't specify the --from version?

The command requires --from to establish the version range for codemod selection. If omitted, the CLI will error out after validating arguments (lines 88–96 in upgrade.mjs). You must specify the version you are migrating from so the registry can determine which transforms to apply.

How does the command handle breaking changes in codemods?

Breaking changes are managed through the registry's version manifests. Each codemod is tagged with a target version. The getTransformsBetween() function only applies transforms relevant to your specific version range. Optional codemods (marked with optional: true) are skipped by default unless explicitly requested with --codemod, preventing unexpected breaking changes.

Can I run integration-specific codemods without core codemods?

No, the current implementation in packages/cli/src/commands/upgrade.mjs runs core codemods first, then optionally runs integration codemods if --integration is provided. There is no flag to run only integration codemods while skipping core transforms. However, you can use --skip-codemod to skip specific core transforms that you don't want to execute.

Where does the command look for the installed core package?

The detectInstalledTargetVersion() function scans node_modules/@astryxdesign/core/package.json for the version field. If that package is not found, it falls back to the legacy @xds/core package path (lines 60–78). This detection happens automatically before any codemods are selected or executed.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →