StyleX Documentation
website·Indexed 35 days ago
https://stylexjs.comStyleX 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.
What's inside StyleX
- StyleX is a styling system that combines the ergonomics of authoring styles inline with the predictability and performance of atomic CSS.
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.
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:hoveror: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, andstylex.when.descendant) rely on the CSS:has()selector, which may not have full browser support.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.,
marginvsmargin-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.
Configure shareable tokens and functions with stylex.env
Thestylex.envAPI 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.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.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
camelCaseinstead 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.
- Property Naming: Uses familiar CSS property names in
Set up the CSS entrypoint for StyleX
To ensure StyleX styles are correctly loaded, you must have at least one CSS file imported from your root layout component or your main JavaScript entry point.Define pseudo-elements in StyleX
Pseudo-elements (like::placeholder) must be defined as top-level keys within a style namespace.import * as stylex from '@stylexjs/stylex'; const styles = stylex.create({ input: { '::placeholder': { color: '#999', }, color: { default: '#333', ':invalid': 'red', }, }, });Set up a CSS entrypoint for StyleX in Vite
To ensure Vite emits a CSS asset and to avoid extra network requests in production, import a CSS file (e.g.,src/index.css) from the application root. During thevite buildprocess, the StyleX plugin appends its aggregated compiled output to this CSS file.Apply styles using stylex.create and stylex.props
StyleX uses a minimal API surface consisting of two primary functions:
stylex.createto define styles andstylex.propsto apply them to elements.Because StyleX relies on standard JavaScript patterns, conditional styling is handled via boolean or ternary expressions within the
stylex.propscall 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)} />; }Maintain type-safety when creating themes
When a variable is declared with a specific type indefineVars, you must use the corresponding type function when overriding that variable instylex.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), });