# How to Use the Astryx Swizzle Command to Eject Component Source Code

> Easily eject component source code from the Astryx library using the swizzle command. Customize JSX, styling, and props by copying source files directly into your project.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-02

---

**The Astryx swizzle command copies component source files from the `@astryxdesign/core` package into your local project, rewriting imports so you can customize JSX, styling, and props without forking the entire library.**

The `facebook/astryx` repository provides a CLI tool that lets developers extract and modify component source code directly. The **Astryx swizzle command** is the primary mechanism for "ejecting" components, moving them from the distributed package into your project's source tree while maintaining the design system's feedback loop.

## How the Swizzle Command Works

The `swizzle` implementation in `packages/cli/src/commands/swizzle.mjs` executes a five-step workflow to safely transfer component source code.

### Component Discovery

First, the command identifies the **owning package** for the requested component. Core components live under `@astryxdesign/core`, while integration components are discovered via the logic in `packages/cli/src/lib/component-discovery.mjs`. This ensures the CLI locates the correct source directory regardless of whether you are extracting a core button or a third-party integration component.

### File Copying and Filtering

The command copies all source files—such as `.tsx`, `.ts`, and `.css`—while explicitly excluding test files and documentation. By default, files are written to `./components/astryx/<ComponentName>`, though you can customize this target directory.

### Import Path Rewriting

Relative imports that escape the component folder are automatically transformed to reference the owning package's sub-path. For example, the helper `rewriteImports` (lines 54-68 in `packages/cli/src/commands/swizzle.mjs`) converts `../utils/mergeProps` into `@astryxdesign/core/utils`. This ensures your ejected component remains compatible with the original package's utilities while using standard Node.js module resolution.

### Path Safety Validation

Before writing any files, the CLI validates the output directory using `packages/cli/src/utils/path-safety.mjs`. If your specified path resolves outside the current working directory, the command throws a **PathSafetyError** and aborts, preventing accidental overwrites of system files or other projects.

### Maintainer Feedback

After successful execution, the CLI prints maintainer feedback generated by the `buildFeedback` function (lines 80-98). This includes a link to the component's issue tracker or a ready-to-run `gh` command if the repository is hosted on GitHub, keeping the design system's feedback loop intact.

## CLI Usage Examples

### Listing Available Components

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

```bash
npx astryx swizzle --list

```

### Ejecting a Basic Component

To copy the Button component source into the default `./components/astryx` directory:

```bash
npx astryx swizzle Button

```

### Specifying a Custom Output Directory

Target a specific folder in your source tree using the `--output` flag:

```bash
npx astryx swizzle Button --output src/custom-components

```

### Force Overwriting Existing Files

If you have previously swizzled a component and want to replace it with a fresh copy, use the force flag:

```bash
npx astryx swizzle Button -f

```

### Machine-Readable JSON Output

For CI/CD pipelines or programmatic consumption, use the `--json` flag:

```bash
npx astryx --json swizzle Button

```

The output follows the structure defined in `packages/cli/src/lib/json.mjs`:

```json
{
  "type": "swizzle.copy",
  "data": {
    "component": "Button",
    "package": "@astryxdesign/core",
    "outputDir": "components/astryx/Button",
    "filesCopied": 5,
    "files": ["Button.tsx","Button.stylex.ts","index.ts","utils.ts","types.ts"],
    "feedback": {
      "issuesUrl": "https://github.com/facebook/astryx/issues/new",
      "ghCommand": "gh issue create --repo facebook/astryx --title \"[Button] Swizzle feedback\""
    }
  }
}

```

## Programmatic Integration

You can invoke the swizzle command programmatically by importing the registration function from the CLI library:

```typescript
import { registerSwizzle } from '@astryxdesign/cli';
import { Command } from 'commander';

const program = new Command();
registerSwizzle(program);

// Equivalent to `npx astryx swizzle Button`
program.parse(['node', 'astryx', 'swizzle', 'Button']);

```

This approach is useful for building custom tooling or integrating the swizzle workflow into larger build scripts.

## Summary

- The **Astryx swizzle command** ejects component source code from `@astryxdesign/core` into your local project.
- The `rewriteImports` function (lines 54-68 in `swizzle.mjs`) transforms relative imports to package sub-paths like `@astryxdesign/core/utils`.
- **PathSafetyError** prevention in `packages/cli/src/utils/path-safety.mjs` ensures output stays within your project directory.
- JSON mode (`--json`) outputs structured data via `packages/cli/src/lib/json.mjs` for automation.
- The original component remains untouched; your custom version lives in the specified output directory (default `./components/astryx`).

## Frequently Asked Questions

### What file types does the swizzle command copy?

The command copies all non-test, non-documentation source files including `.tsx`, `.ts`, and `.css` files. It excludes test suites, stories, and markdown documentation to ensure you receive only the implementation code needed for customization.

### How does swizzle handle imports that reference files outside the component folder?

The `rewriteImports` helper in `packages/cli/src/commands/swizzle.mjs` (lines 54-68) automatically transforms escape-hatch imports. For example, `../utils/mergeProps` becomes `@astryxdesign/core/utils`, ensuring your ejected component can still access shared utilities without requiring relative path traversals outside the package.

### Can I swizzle components from integration packages, not just core?

Yes. The `component-discovery.mjs` module in `packages/cli/src/lib/` distinguishes between core components (`@astryxdesign/core`) and integration components, allowing you to eject source code from any registered package in the Astryx ecosystem.

### What happens if I specify an output directory outside my project?

The command throws a **PathSafetyError** from `packages/cli/src/utils/path-safety.mjs` and aborts the operation. This safety check prevents the CLI from writing files to system directories or sibling projects, ensuring all swizzled code remains within your repository's working directory.