How to Use the Astryx Swizzle Command to Eject Component Source Code
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:
npx astryx swizzle --list
Ejecting a Basic Component
To copy the Button component source into the default ./components/astryx directory:
npx astryx swizzle Button
Specifying a Custom Output Directory
Target a specific folder in your source tree using the --output flag:
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:
npx astryx swizzle Button -f
Machine-Readable JSON Output
For CI/CD pipelines or programmatic consumption, use the --json flag:
npx astryx --json swizzle Button
The output follows the structure defined in packages/cli/src/lib/json.mjs:
{
"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:
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/coreinto your local project. - The
rewriteImportsfunction (lines 54-68 inswizzle.mjs) transforms relative imports to package sub-paths like@astryxdesign/core/utils. - PathSafetyError prevention in
packages/cli/src/utils/path-safety.mjsensures output stays within your project directory. - JSON mode (
--json) outputs structured data viapackages/cli/src/lib/json.mjsfor 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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →