# How to Run Tests in Astryx: Complete Guide to Vitest Setup and Commands

> Master running tests in Astryx with our comprehensive guide. Learn Vitest setup and commands for efficient UI and Node testing.

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

---

**Run tests in Astryx using `pnpm test`, which executes two parallel Vitest projects—UI tests in a jsdom environment and Node tests in a pure Node environment—defined in [`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts).**

Astryx, Facebook's design system monorepo, uses **Vitest** as its test runner with a sophisticated dual-project configuration. Whether you're testing React components with DOM interactions or CLI utilities with filesystem operations, understanding how to run tests in Astryx ensures you can validate changes efficiently across the entire codebase.

## Test Framework and Architecture

Astryx's test suite is orchestrated from the root [[`package.json`](https://github.com/facebook/astryx/blob/main/package.json)](https://github.com/facebook/astryx/blob/main/package.json) and configured centrally in [[`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts)](https://github.com/facebook/astryx/blob/main/vitest.config.ts). The setup splits tests into two distinct **Vitest projects** that run in parallel:

- **ui project**: Component tests requiring DOM access (React components, StyleX transforms, accessibility checks)
- **node project**: Pure Node.js code (CLI tools, build scripts, internal utilities)

This separation optimizes performance and ensures correct environments for different test types.

## Essential Commands to Run Tests in Astryx

All test commands use **pnpm** and are defined in the root [`package.json`](https://github.com/facebook/astryx/blob/main/package.json):

```bash

# Install dependencies (required first step)

pnpm install

# Run the complete test suite (UI + Node projects)

pnpm test

# Continuous watch mode for development

pnpm test:watch

# Generate coverage report (outputs to ./coverage)

pnpm test:coverage

```

### Running Specific Test Projects

For focused development, target individual projects directly:

```bash

# UI tests only (React components, DOM-dependent code)

vitest run --project ui

# Node tests only (CLI, utilities, build tools)

vitest run --project node

# Single test file execution

vitest run packages/core/src/Button/Button.test.tsx

```

## Vitest Configuration Deep Dive

The [[`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts)](https://github.com/facebook/astryx/blob/main/vitest.config.ts) file defines both projects with carefully tuned settings:

**UI Project Configuration:**
- **Environment**: `jsdom` with `globals: true` for automatic test globals
- **Setup file**: [`./internal/test-utils/src/setup.ts`](https://github.com/facebook/astryx/blob/main/./internal/test-utils/src/setup.ts) injects jest-dom matchers and polyfills `matchMedia`/Popover API
- **Coverage scope**: Limited to `packages/**/src/**/*.{ts,tsx}` using V8 provider

**Node Project Configuration:**
- **Critical isolation**: Does **not** extend root config to avoid DOM overhead
- **Worker strategy**: Uses `forks` pool for tests that modify the working directory
- **Global setup**: [`vitest.global-setup.node.mjs`](https://github.com/facebook/astryx/blob/main/vitest.global-setup.node.mjs) pre-builds `@astryxdesign/core` once before workers start, preventing race conditions

### Project Include Patterns

| Project | Packages Included |
|---------|-------------------|
| ui | `core`, `lab`, `charts` |
| node | All remaining packages |

## Key Configuration Files

| File | Purpose |
|------|---------|
| [[`package.json`](https://github.com/facebook/astryx/blob/main/package.json)](https://github.com/facebook/astryx/blob/main/package.json) | Script definitions (`test`, `test:watch`, `test:coverage`) |
| [[`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts)](https://github.com/facebook/astryx/blob/main/vitest.config.ts) | Dual-project Vitest configuration with Babel/StyleX integration |
| [[`internal/test-utils/src/setup.ts`](https://github.com/facebook/astryx/blob/main/internal/test-utils/src/setup.ts)](https://github.com/facebook/astryx/blob/main/internal/test-utils/src/setup.ts) | Global DOM setup, jest-dom matchers, Testing Library defaults |
| [`vitest.global-setup.node.mjs`](https://github.com/facebook/astryx/blob/main/vitest.global-setup.node.mjs) | Node-project build orchestration |
| [[`pnpm-workspace.yaml`](https://github.com/facebook/astryx/blob/main/pnpm-workspace.yaml)](https://github.com/facebook/astryx/blob/main/pnpm-workspace.yaml) | Monorepo workspace boundaries |

## Coverage and Reporting

Coverage collection in Astryx uses **V8** with three reporters:

```bash

# Text summary in terminal + JSON data + HTML report

pnpm test:coverage

```

Reports output to `./coverage/` with HTML visualization. The coverage boundary excludes test files and build artifacts, focusing solely on source code under `packages/**/src/`.

## Troubleshooting Common Issues

**Build race conditions**: The Node project's global setup in `vitest.global-setup.node.mjs` explicitly builds `@astryxdesign/core` once before worker processes spawn. This prevents multiple concurrent builds when test files import the built package.

**DOM environment mismatch**: If you see `document is not defined`, your test file is likely running in the Node project. Move it to `packages/core`, `lab`, or `charts`, or adjust the include patterns in [`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts).

## Summary

- **Primary command**: `pnpm test` runs both UI and Node projects via `vitest run`
- **Architecture**: Dual-project setup separates jsdom and Node environments for optimal performance
- **Watch mode**: `pnpm test:watch` enables continuous feedback during development
- **Coverage**: V8-powered with text/JSON/HTML reporters, scoped to `packages/**/src/`
- **Key files**: [`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts) (central config), [`internal/test-utils/src/setup.ts`](https://github.com/facebook/astryx/blob/main/internal/test-utils/src/setup.ts) (DOM setup), `vitest.global-setup.node.mjs` (Node build orchestration)

## Frequently Asked Questions

### What test runner does Astryx use?

Astryx uses **Vitest** as its test runner. The configuration is defined in [`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts) at the repository root, with npm scripts in [`package.json`](https://github.com/facebook/astryx/blob/main/package.json) providing convenient entry points like `pnpm test` and `pnpm test:watch`. Vitest was chosen for its native ESM support, fast execution, and compatibility with Vite-based tooling.

### How do I run only the UI tests in Astryx?

Use `vitest run --project ui` to execute only the UI project. This runs tests from `packages/core`, `packages/lab`, and `packages/charts` in a jsdom environment with DOM matchers and StyleX transforms enabled. This is useful when developing React components without the overhead of running CLI tests.

### Why does Astryx have two separate test projects?

The **ui** and **node** projects isolate **environment requirements** and **execution strategies**. UI tests need jsdom, jest-dom matchers, and StyleX compilation, while Node tests require a `forks` worker pool for filesystem isolation and must avoid DOM initialization overhead. The Node project also performs a global setup build that would be unnecessary and slow for UI tests.

### Where is coverage configured in Astryx?

Coverage is configured in the root `test` block of [[`vitest.config.ts`](https://github.com/facebook/astryx/blob/main/vitest.config.ts)](https://github.com/facebook/astryx/blob/main/vitest.config.ts). It uses the V8 provider with reporters for `text`, `json`, and `html` output, and includes only source files matching `packages/**/src/**/*.{ts,tsx}`. The HTML report generates in `./coverage/` after running `pnpm test:coverage`.