How to Use the Swizzle Command to Eject Source Code in Astryx

The swizzle command copies a component's full source code from the Astryx design system into your project, rewriting imports and excluding tests to make the component fully customizable.

The swizzle command in the facebook/astryx repository provides a deterministic way to eject components from the Astryx design system into your local codebase. This CLI tool resolves component ownership, rewrites internal imports, and preserves the component's functionality while giving you full control over the implementation. Whether you need to customize a core component or adapt an integration package, understanding how to use the swizzle command to eject source code in Astryx ensures you maintain correct dependencies and project structure.

What the Swizzle Command Does

The swizzle command, implemented in packages/cli/src/commands/swizzle.mjs, performs an atomic ejection of a component's source files from the design-system package into your project directory. It begins by calling resolveOwners to identify whether the component belongs to @astryxdesign/core or a loaded integration package. The command then validates the output path using assertWithin to prevent path-traversal attacks, ensuring the destination stays within your current working directory.

During the copy process, swizzle filters out test files (*.test.*), documentation files (*.doc.*), and README.md entries. For TypeScript files, the rewriteImports function transforms relative imports that climb out of the component directory into absolute package references. For example, ../utils/mergeProps becomes @astryxdesign/core/utils/mergeProps. If the component uses StyleX (detected via @stylexjs/stylex imports), the CLI warns that a StyleX compiler is required for proper rendering.

How to Eject a Component with Swizzle

Listing Available Components

Before ejecting, list all swizzlable components to verify the exact name:

npx astryx swizzle --list

This queries the core package and any loaded integrations, displaying available components like Button, Card, and Modal.

Basic Ejection of a Core Component

To eject a core component such as Button, run:

npx astryx swizzle Button

The command copies the Button source to ./components/astryx/Button by default. It rewrites all relative imports to point to @astryxdesign/core and displays a summary including the number of files copied and any StyleX dependencies.

Ejecting from Integration Packages

When components exist in multiple packages, specify the source using --package:

npx astryx swizzle XDSButton --package @astryxdesign/experimental

The command automatically strips integration prefixes (converting XDSButton to Button) and resolves the component via the integration's source directory.

Safety and Path Validation

The CLI enforces security through packages/cli/src/utils/path-safety.mjs. The assertWithin utility guarantees that the --output directory remains inside your project root, rejecting attempts to write to system directories or parent folders. This protection runs before any file operations begin, ensuring deterministic and safe ejection behavior.

Advanced Usage Options

Overwriting Existing Files

To bypass confirmation prompts and replace existing files, use the force flag:

npx astryx swizzle Card -f

The -f (or --overwrite) flag immediately overwrites colliding files in the target directory without interactive confirmation.

JSON Output for Automation

For CI/CD pipelines or scripting, output machine-readable JSON:

npx astryx swizzle Modal --json

Sample output:

{
  "component": "Modal",
  "package": "@astryxdesign/core",
  "outputDir": "components/astryx/Modal",
  "filesCopied": 12,
  "files": ["Modal.tsx", "Modal.stylex.ts", "utils.ts"],
  "usesStyleX": true,
  "feedback": {
    "issuesUrl": "https://github.com/facebook/astryx/issues/new",
    "ghCommand": "gh issue create --repo facebook/astryx --title \"[Modal] Swizzle feedback\""
  }
}

The JSON includes the feedback URL and GitHub CLI command, encouraging you to notify maintainers why you needed to swizzle the component.

Summary

  • The swizzle command ejects components from packages/cli/src/commands/swizzle.mjs by resolving ownership through resolveOwners and validating paths with assertWithin.
  • It automatically rewrites relative imports to package-scoped imports using rewriteImports and excludes test and documentation files.
  • StyleX usage is detected and reported, ensuring you know when to configure a StyleX compiler.
  • Use --package to target integration components, -f to force overwrites, and --json for programmatic integration.

Frequently Asked Questions

What does the swizzle command do in Astryx?

The swizzle command copies a component's complete source code from the Astryx design system into your local project. It preserves functionality by rewriting internal imports and excluding non-essential files like tests, allowing you to customize the component while maintaining the rest of the design system intact.

How does swizzle handle relative imports when ejecting code?

During ejection, swizzle invokes rewriteImports to transform relative paths that reference parent directories into absolute package imports. For instance, an import like ../utils/mergeProps is rewritten to @astryxdesign/core/utils/mergeProps, ensuring the ejected component can resolve its dependencies correctly.

Can I swizzle components from integration packages?

Yes. When multiple packages own a component, use the --package flag to specify the source, such as @astryxdesign/experimental. The command automatically strips integration-specific prefixes (like XDS) and resolves the component through the integration's source directory.

What files are excluded when using the swizzle command?

The command filters out test files (*.test.*), documentation files (*.doc.*), and README.md entries from the copied source. This ensures you receive only the implementation code necessary for the component to function in your project.

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 →