StyleX Documentation

website·Indexed 35 days ago

https://stylexjs.com

StyleX combines the ergonomics of authoring styles inline with the predictability and performance of atomic CSS. The documentation covers the JavaScript API (including stylex.create, stylex.props, and stylex.defineVars), type definitions like StyleXStyles and VarGroup, and configuration for plugins such as @stylexjs/babel-plugin, @stylexjs/eslint-plugin, @stylexjs/postcss-plugin, and @stylexjs/unplugin. It also provides installation guides for Bun, CLI, and @stylexjs/create.

Tokens
27.1K
Snippets
156
Records
191
Agent score
70%

What's inside StyleX

  1. Overview of StyleX features

    StyleX is a CSS-in-JS library that generates optimized, collision-free atomic CSS at compile-time. Key benefits include:

    • Scalability: CSS bundle size plateaus as the codebase grows due to atomic CSS.
    • Predictability: Eliminates specificity issues and "style at a distance"; the last applied style for a property always wins.
    • Composability: Supports conditional styling, merging arbitrary styles, and passing styles as props.
    • Performance: No runtime style injection; it generates static CSS files and uses a tiny runtime for merging class names.
    • Type-Safety: Provides type-safe APIs for styles and themes.
  2. Overview of stylex.when contextual selectors

    The stylex.when.* suite of APIs allows you to style an element based on the state of its ancestors, descendants, or siblings. You can observe pseudo-classes (like :hover or :focus) or attribute selectors (like [data-state="open"]).

    To make these selectors work, the element being observed must be marked with a marker class, typically stylex.defaultMarker().

    Caveat: Lookahead selectors (stylex.when.siblingAfter, stylex.when.anySibling, and stylex.when.descendant) rely on the CSS :has() selector, which may not have full browser support.

  3. Understand StyleX core principles and styling philosophy

    StyleX is a deterministic, type-safe CSS-in-JS library designed for high performance and predictability. Its core philosophy centers on:

    • Co-location: Styles are authored in the same file as the markup for better readability and reasoning.
    • Deterministic Resolution: StyleX eliminates CSS specificity conflicts. When merging styles, the last style applied wins. For shorthand vs. longhand properties (e.g., margin vs margin-top), the more specific property (margin-top) always wins regardless of order.
    • Low-cost Abstractions: StyleX shifts work to build-time to minimize runtime overhead. Styles created and applied in the same file are compiled away entirely, resulting in zero runtime cost.
    • Encapsulation: To prevent "styles at a distance," StyleX requires that all styles on an element be caused by class names applied directly to that element, avoiding selectors like .className > * or .className:hover button.
  4. Configure shareable tokens and functions with stylex.env

    The stylex.env API allows you to define shareable tokens and pure functions within your Babel configuration. These values are replaced before compilation, ensuring that identical values deduplicate into a single CSS rule without generating additional CSS. This is an experimental API and is subject to change.
  5. Use StyleX CLI for pre-transforming source files

    The StyleX CLI is used to compile away StyleX and generate a static CSS file for an entire directory of files before the rest of the build pipeline runs. This is recommended when other integrations are not viable. The only requirement is that the project's bundler must be able to handle CSS imports, as the CLI automatically inserts an import for the generated CSS file into every transformed file.
  6. Understand StyleX styling principles and constraints

    StyleX prioritizes readability, maintainability, and predictability over terseness and global configuration:

    • Property Naming: Uses familiar CSS property names in camelCase instead of kebab-case.
    • Separation of Concerns: Styles must be authored in objects separate from HTML elements. This improves markup readability and allows semantic naming (e.g., styles.active) to communicate intent.
    • Inheritance: Only standard inheritable styles (like color) are allowed. Styles applied directly to an element always take precedence over inherited styles.
    • No Global Config: StyleX avoids project-specific configurations or magic strings. All styles and variables are imported as JavaScript modules.
    • CSS Delivery: Optimized for a single, highly optimized CSS bundle loaded upfront to avoid the performance penalties (like INP) associated with lazy-loading CSS and triggering full-page style recalculations.
  7. Apply styles using stylex.create and stylex.props

    StyleX uses a minimal API surface consisting of two primary functions: stylex.create to define styles and stylex.props to apply them to elements.

    Because StyleX relies on standard JavaScript patterns, conditional styling is handled via boolean or ternary expressions within the stylex.props call rather than a specialized API.

    import * as stylex from '@stylexjs/stylex';
    
    const styles = stylex.create({
      red: { color: 'red' },
      blue: { color: 'blue' },
    });
    
    // Applying styles conditionally using JS patterns
    function MyComponent({ isError }) {
      return <div {...stylex.props(isError ? styles.red : styles.blue)} />;
    }
  8. Maintain type-safety when creating themes

    When a variable is declared with a specific type in defineVars, you must use the corresponding type function when overriding that variable in stylex.createTheme. While this is functionally a no-op in the generated CSS, it is required for static type-safety in your source code.
    import * as stylex from '@stylexjs/stylex';
    import { tokens } from './tokens.stylex.js';
    
    export const highContrast = stylex.createTheme(tokens, {
      primaryText: stylex.types.color('black'),
      secondaryText: stylex.types.color('#222'),
      borderRadius: stylex.types.length('8px'),
      angle: stylex.types.angle('0deg'),
      int: stylex.types.integer(4),
    });