# How the Astryx CLI Build Command Handles StyleX Source Builds vs. Pre‑Compiled CSS

> Learn how Astryx CLI build command handles StyleX source builds versus pre-compiled CSS. Discover how it efficiently compiles or reuses CSS files to optimize your build process.

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

---

**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`](https://github.com/facebook/astryx/blob/main/.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 build` across the monorepo
- Transpiles [`.ts/.tsx`](https://github.com/facebook/astryx/blob/main/.ts/.tsx) files to JavaScript
- Emits intermediate [`.stylex.ts`](https://github.com/facebook/astryx/blob/main/.stylex.ts) files containing raw StyleX definitions to each package's `dist/` directory

These [`.stylex.ts`](https://github.com/facebook/astryx/blob/main/.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:

```javascript
// 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`](https://github.com/facebook/astryx/blob/main/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:

```javascript
// 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`](https://github.com/facebook/astryx/blob/main/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 `.tgz` archive
- 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

```bash

# 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`](https://github.com/facebook/astryx/blob/main/.stylex.ts)) require processing through `scripts/build-css.mjs` using the `@astryxdesign/build` extractor
- **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`](https://github.com/facebook/astryx/blob/main/.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`](https://github.com/facebook/astryx/blob/main/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.