How the Astryx CLI Build Command Handles StyleX Source Builds vs. Pre‑Compiled CSS
The Astryx CLI build command compiles TypeScript/StyleX source files into CSS via a dedicated extraction script, but skips that expensive step and reuses existing CSS files when they are already present.
The @astryxdesign build pipeline in the facebook/astryx repository separates StyleX source compilation from CSS generation to maximize cache efficiency in CI environments. Understanding how the CLI distinguishes between raw .stylex.ts sources and pre‑built stylesheets helps developers optimize their build times and debug packaging issues.
The Two‑Phase Build Architecture
Phase 1: TypeScript and StyleX Source Compilation
The build process begins in packages/cli/clients/cli/commands/build.mjs, which delegates to the ensure‑core‑built helper at packages/cli/clients/cli/commands/ensure-core-built.mjs.
This phase:
- Runs
pnpm buildacross the monorepo - Transpiles
.ts/.tsxfiles to JavaScript - Emits intermediate
.stylex.tsfiles containing raw StyleX definitions to each package'sdist/directory
These .stylex.ts files are not yet CSS—they are JavaScript modules that export style objects that must be transformed.
Phase 2: CSS Extraction via build‑css.mjs
Once TypeScript compilation completes, control passes to scripts/build-css.mjs. This script performs the actual StyleX-to-CSS conversion:
// scripts/build-css.mjs (conceptual flow)
import { extract } from '@astryxdesign/build';
// Walk dist/ tree, find .stylex.ts modules
// Extract declarative StyleX objects → plain CSS rules
// Write single stylesheet per package (e.g., packages/core/dist/astryx.css)
The @astryxdesign/build extractor (implemented in packages/build/src/extract.mjs) parses the style objects and generates optimized CSS. The CLI then updates each package's package.json with a stylex:css field pointing to the compiled stylesheet location.
How Pre‑Compiled CSS Short‑Circuits the Pipeline
The CLI avoids redundant work through a deterministic check in the ensure‑core‑built helper:
// packages/cli/clients/cli/commands/build.mjs (simplified)
import { ensureCoreBuilt } from './ensure-core-built.mjs';
import { runBuildCss } from '../../scripts/build-css.mjs';
export async function run() {
await ensureCoreBuilt(); // Step 1: Compile TS sources
if (!await cssAlreadyExists()) { // Step 2: Check for cached CSS
await runBuildCss(); // Step 2b: Extract only if needed
}
// Step 3: Theme packaging, manifest generation, tarball creation
}
When cssAlreadyExists() finds the expected CSS file (e.g., packages/core/dist/astryx.css), the CLI prints:
CSS already present – skipping build-css
This optimization is critical for parallel CI jobs and incremental builds. Cached dist/ directories from previous runs allow the command to bypass the relatively expensive StyleX parsing pass entirely.
Final Packaging and Theme Pipeline
With CSS guaranteed present—whether freshly extracted or pre‑existing—the CLI executes the @astryxdesign/build theme pipeline at packages/cli/api/theme/build/build.mjs. This stage:
- Bundles compiled CSS with JavaScript assets
- Generates the final publishable
.tgzarchive - Updates the workspace lockfile
The separation between source transformation and CSS extraction means the theme pipeline operates on finalized artifacts without needing to distinguish their origin.
Key Implementation Files
| Purpose | File Path |
|---|---|
CLI build command orchestrator |
packages/cli/clients/cli/commands/build.mjs |
| Core compilation guarantee helper | packages/cli/clients/cli/commands/ensure-core-built.mjs |
| Post‑build CSS extraction script | scripts/build-css.mjs |
| Theme packaging pipeline | packages/cli/api/theme/build/build.mjs |
| StyleX extraction library | packages/build/src/extract.mjs |
Build Command Examples
# Full build: compile TypeScript, extract StyleX, generate CSS
$ astryx build
# Fast path: skip CSS extraction when dist/ is cached
# (automatically detected; manual flag for explicit control)
$ astryx build --skip-css
Summary
- Raw StyleX sources (
.stylex.ts) require processing throughscripts/build-css.mjsusing the@astryxdesign/buildextractor - Pre‑compiled CSS is detected via file existence checks in
ensure-core-built.mjs, enabling cache‑friendly incremental builds - The CLI's two‑phase architecture separates TypeScript compilation from CSS generation to maximize parallelism and avoid redundant work
- Final packaging occurs through the theme pipeline at
packages/cli/api/theme/build/build.mjs, regardless of CSS origin
Frequently Asked Questions
How does Astryx detect whether CSS needs to be rebuilt?
The ensure-core-built.mjs helper checks for the presence of expected CSS files in each package's dist/ directory. If packages/*/dist/*.css exists and matches the expected naming convention, the CLI assumes the CSS is current and bypasses the build-css.mjs extraction step.
Can I force CSS regeneration even when cached files exist?
The CLI supports a --skip-css flag for explicit control (used inversely to skip generation). To force regeneration in environments with partial caches, clear the dist/ directories before running astryx build, or use environment-specific CI configurations that scope cache keys to source file hashes.
What format do the intermediate .stylex.ts files use?
These files export JavaScript objects containing StyleX style definitions—essentially the raw output of the StyleX transformer before CSS extraction. The @astryxdesign/build extractor in packages/build/src/extract.mjs consumes these objects and emits atomic CSS rules with hashed class names.
Where does the final CSS get referenced for downstream consumers?
After extraction completes, the CLI updates each package's package.json with a stylex:css field pointing to the generated stylesheet path. This metadata allows dependent packages to discover and bundle the CSS without hardcoding paths.
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 →