Skip to main content

· 4 min read
Naman Goel
Melissa Liu

StyleX v0.17 introduces an all new unplugin package for improved integration with various modern bundlers, the ability to define custom markers for use with stylex.when.* APIs, and a slew of bug-fixes and improvements.

New @stylexjs/unplugin package

Stylex 0.17 comes with a new @stylexjs/unplugin package that use the excellent unplugin library to create a near-universal bundler plugin that works with Vite, Rollup, Webpack, Rspack, Esbuild, and more. In supported project setups, this new package should offer the best developer experience and performance for StyleX integration. We've introduced new examples for Webpack, RSPack, and various Vite setups (RSCs, React-Router, Waky and RedwoodSDK) with testing for both production builds and HMR in development builds when applicable. For frameworks that are not yet supported by our unplugin package, we continue to maintain the @stylexjs/postcss-plugin and and @stylexjs/cli packages for maximum compatibitiy.

We look forward to expanding this set of examples with more common frameworks and bundler setups.

Custom Markers for stylex.when.* APIs

StyleX 0.16 introduced new set of APIs to observe the state of other elements:

  • stylex.when.ancestor(pseudo, marker?)
  • stylex.when.descendant(pseudo, marker?)
  • stylex.when.siblingBefore(pseudo, marker?)
  • stylex.when.siblingAfter(pseudo, marker?)
  • stylex.when.anySibling(pseudo, marker?)
  • stylex.defaultMarker()

StyleX 0.17 introduces one new API to create custom named markers, stylex.defineMarker().

Using these APIs, a typical CSS selector such as .parent:hover .child can be implemented as:

Hovering here makes the button pink and the arrow opaque

// markers.stylex.ts
import * as stylex from '@stylexjs/stylex';

export const cardMarker = stylex.defineMarker();
export const btn = stylex.defineMarker();
// Card.tsx
import * as stylex from '@stylexjs/stylex';
import { cardMarker, btnMarker } from './markers.stylex';
import {tokens} from './tokens.stylex';

export function Card() {
return (
<article {...stylex.props(styles.card, cardMarker)}>
<p>Markers let siblings and ancestors opt into the same state.</p>
<button {...stylex.props(btnMarker, styles.cta)}>
Action
<ArrowIcon style={styles.icon} />
</button>
</article>
);
}

const styles = stylex.create({
card: {
borderWidth: 1,
borderStyle: 'solid',
borderColor: tokens.borderColor,
},
cta: {
backgroundColor: {
default: 'black',
[stylex.when.ancestor(':hover', cardMarker)]: tokens.accent,
},
color: 'white',
},
icon: {
opacity: {
default: 0,
[stylex.when.ancestor(':hover', cardMarker)]: 1,
},
transform: {
default: 'translateX(0)',
[stylex.when.ancestor(':hover', btnMarker)]: 'translateX(4px)',
}
}
});

Icon in the button appears when card is hovered, but it moves to the right when the button itself is hovered.

Updating default configuration options

We are updating some of the default StyleX configuration options to help make the builds more consistent across development and production and improve the developer experience in many scenarios.

enableDebugClassNames is now disabled by default

Enabling this option will emit classNames that reference the CSS property being applied, and CSS variable names that are prefixed with the name used in source. However, generating incompatible CSS in development and production can cause caching-related bugs in some setups and so we are disabling this option by default.

data-style-src prop now shows full file paths

The data-style-src prop is injected in addition to className and style during development to help identify the list of style objects applied to to the element in order or application. Previously, it showed only the last two segments of the file path which can be confusing.

Now, the it will include the full path relative to the nearest package.json file. For third-party package, we will also include the package name itself.

enableDevClassNames will now be enabled when dev is enabled

The dev option inserts additional classNames that help identify where various classNames are coming from.

enableMediaQueryOrder is now enabled by default

This config ensures that authored media query order is respected, with later queries taking precedence over earlier ones.

Other Improvements

  • Added support for handling defineConsts correctly when runtime injection is enabled.
  • Fixed a bug sometimes that caused invalid CSS output when media queries use screen and conditionals
  • Dependency updates, including Jest, to pick up the latest fixes. (Thanks @vincentriemer, @jcperez-ch!)
  • Specificity improvements when using stylex.when.* selectors alongside regular pseudo-classes.
  • Expand how often stylex.props is precompiled to improve performance.
  • Various improvements to Flow and Typescript types. (Thanks @j-malt, @henryqdineen!)
  • Various improvements and fixes to the ESlint plugin, including support for defineConsts in enforce-extension, and improvements to sort-key ordering. (Thanks @hiteshshetty-dev, @yjoer, @dwei-figma!)

· 3 min read
Melissa Liu
Naman Goel

This release adds support for a long-requested feature—descendant and sibling selectors! We've also expanded defineConsts capabilities, improved our lint rules, added a webpack example, and made some performance optimizations.

Descendant and sibling selectors

We’re adding a new suite of APIs under stylex.when with support for descendant and sibling selectors: ancestor, descendant, anySibling, siblingBefore, and siblingAfter.

  • Ancestor/descendant (stylex.when.ancestor and stylex.when.descendant) selectors let you style an element based on the state of ancestors or descendants in the DOM tree.
  • Sibling selectors (stylex.when.anySibling, stylex.when.siblingBefore and stylex.when.siblingAfter) let you style an element based on the state of adjacent siblings.

To use descendant and sibling selectors, you'll need to mark the element being observed by passing the stylex.defaultMarker class name. Support for custom markers will be added in a future release.

import * as stylex from '@stylexjs/stylex';

const styles = stylex.create({
foo: {
backgroundColor: {
default: 'blue',
[stylex.when.ancestor(':hover')]: 'red',
},
},
});

<div {...stylex.props(stylex.defaultMarker())}>
<div {...stylex.props(styles.foo)}> Some Content </div>
</div>

Note: Lookahead selectors like stylex.when.siblingAfter, stylex.when.anySibling, and stylex.when.descendant rely on the CSS has() selector, which does not yet have widespread browser support.

defineConsts improvements

We’ve added support for overriding defineConsts constants that reference CSS variables (var(--*)) when set to variables and variable fallbacks. Constants now behave like passthroughs, with overrides applying to the original CSS variable. This allows you to re-define them within create calls as you would for defineVars.

export const colors = stylex.defineConsts({
bg: "var(--background-color)",
accent: "var(--accent, lightblue)",
});

import {colors} from "./colors.stylex.js";
const styles = stylex.create({
root: {
[colors.bg]: "red",
[colors.accent]: "darkblue",
},
});

We've also added support for defineConsts in dynamic styles. You can now use defineConsts to declare media queries within dynamic styles as you would in regular StyleX namespaces.

const style = stylex.create({
main: (height) => ({
color: {
default: colors.red,
[breakpoints.sm]: colors.blue,
[breakpoints.md]: colors.yellow,
},
height: height - 10,
}),
});

Linter improvements

We made several improvements and lint fixes to the valid-styles rule. The valid-styles rule now has support for locally resolved constants.

const HEIGHT = 5;

const styles = stylex.create({
default: {
scrollMarginTop: HEIGHT + 5,
scrollMarginBottom: HEIGHT * 5,
},
});

We added linter support for setting CSS custom properties within create calls. (Thanks @dwei-figma!)

const styles = stylex.create({
default: {
--background-color: 'red',
},
});

We also added support for positionTry styles (Thanks @abhakat!), better validation for pseudo-elements (Thanks @dwrth!), migrated object type validation to Flow (Thanks @jcperez-ch!), and of 0 values as strings ('0') for length properties.

Bug fixes

  • Fixed class name construction for dynamic contextual styles.
  • Reduced chances of dynamic variable name collisions. (Thanks @necolas!)

Miscellaneous

  • A webpack example was added to our suite of StyleX example integrations! (Thanks @RavenColEvol!)
  • Support to hoist stylex.create and nested objects within functions.
  • Optimized precomputed props calls in JSX. (Thanks @necolas!)
  • More efficient handling of null/undefined in dynamic styles.

· 2 min read
Melissa Liu

StyleX v0.15.0 introduces significant improvements to media query handling, dynamic styles optimization, and improvements to the linter, types, and documentation.

Media query ordering

Previously, media queries within a style property were applied in a predetermined sorting order. This often meant that the order you authored the queries did not match how they were applied, so we recommended manually ensuring your media queries didn’t overlap to prevent unexpected overrides in behavior.

We've integrated our in-house media query parser and transformer to handle this automatically. You can now write overlapping media queries in a contextual style in the order you desire, and the compiler will rewrite them so that later queries take precedence over earlier ones.

The compiler now also validates media query syntax and simplifies complex queries when possible, opening the door to later optimizations.

As an example, take this create call:

const styles = stylex.create({
foo: {
    gridColumn: {
      default: '1 / 2',
      '@media (max-width: 1440px)': '1 / 4',
      '@media (max-width: 1024px)': '1 / 3',
      '@media (max-width: 768px)': '1 / -1',
    },
},
});

This is now transformed at compile time to:

const styles = stylex.create({
foo: {
    gridColumn: {
      default: '1 / 2',
      '@media (max-width: 1440px) and (min-width: 1024.01px)': '1 / 4',
      '@media (min-width: 768.01px) and (max-width: 1024px)': '1 / 3',
      '@media (max-width: 768px)': '1 / -1',
    },
  },
});

This new feature is gated behind the config option enableMediaQueryOrder.

Dynamic styles improvements

Dynamic styles should now work more consistently when given the same values as static styles. Improvements have been made to how we handle null and undefined values.

We've also made optimizations in how we process dynamic styles to improve performance and minimize the amount of generated Javascript. We do this by using heuristics to detect values that can never be nullable.

Fixes

  • Fixed TypeScript types for stylex.types.* functions (Thanks @nmn!)
  • Resolved opaque type issues for InlineStyles. (Thanks @pawelblaszczyk5!)
  • Fixed ESLint utility functions for number and math call validation and added style validation for length properties.

Documentation

  • Added documentation around manual CSS variables generated with defineVars. (Thanks @necolas!)
  • Updated outdated theming docs to align with current createTheme behaviour (Thanks @nmn!)
  • Fixed ESLint rule severity syntax in the installation guide examples and cleaned up docs for descendent styles. (Thanks @sonsu95 and @mtpetros!)

· 2 min read
Vincent Riemer
Melissa Liu

StyleX v0.14.0 introduces new APIs to the compiler and linter, as well as a couple of breaking changes to improve performance.

New features

Compiler: viewTransitionClass

The viewTransitionClass API allows you to use StyleX to customize your CSS View Transitions. This API works nicely with React’s new <ViewTransition /> component:

import {unstable_ViewTransition as ViewTransition} from 'react';
import * as stylex from '@stylexjs/stylex';

const transitionClass = stylex.viewTransitionClass({
old: {
animationName: stylex.keyframes({ to: { opacity: 0 } }),
animationTimingFunction: 'ease-out',
animationDuration: '300ms',
},
new: {
animationName: stylex.keyframes({ from: { opacity: 0 } }),
animationTimingFunction: 'ease-out',
animationDuration: '300ms',
},
});

// in a component definition

<ViewTransition default={transitionClass}>
<Content />
</ViewTransition>

Linter: validImports

The @stylexjs/eslint-plugin package now supports the validImports option for all rules, allowing you to configure where the linter expects StyleX to be imported from. This is equivalent to the importSources option for the compiler. Thanks to @javascripter for this improvement.

{
// Default: ['stylex', '@stylexjs/stylex']
validImports: Array<string | { from: string, as: string }>,
}

Breaking changes

Style resolution

StyleX will now use property-specificity instead of application-order as the default value for the styleResolution option (the strategy used to merge styles). The difference between these 2 strategies is as follows:

  • application-order
    • The last style wins, i.e., margin wins over marginTop if it appears last in the order of styles.
    • Larger generated JavaScript objects.
  • property-specificity
    • The more specific style wins, i.e., marginTop wins over margin irrespective of the order of styles.
    • Disallows more shorthands, e.g., background, border.
    • Smaller generated JavaScript objects.

If you experience visual regressions, set styleResolution to application-order. However, the performance metrics we track are all significantly improved or neutral when using property-specificity, therefore, we strongly encourage migration.

Fixes

  • [babel-plugin] Fix theming in dev/debug mode.
  • [eslint-plugin] Add autofix support for all remaining nonstandard CSS properties to the valid-styles rule.
  • [stylex] Fix the TypeScript types. Thanks to @pawelblaszczyk5 for this improvement.

· 3 min read
Melissa Liu

StyleX v0.13.0 introduces two new APIs and several breaking changes to compiler defaults, alongside various bug fixes.

New APIs

defineConsts

We've added a new defineConsts API to allow for declaration and use of constant values. Unlike defineVars, these are inlined at build-time and do not generate CSS variables. This is a long requested feature that allows for shareable media queries.

constants.stylex.js
export const breakpoints = stylex.defineConsts({
small: '@media (max-width: 600px)',
medium: '@media (min-width: 601px) and (max-width: 1024px)',
large: '@media (min-width: 1025px)',
});

export const colors = stylex.defineConsts({
brand: '#0055FF',
surface: '#FFFFFF',
text: '#111111',
});

You can then import and use these constants in any create call:

import * as stylex from '@stylexjs/stylex';
import { breakpoints, colors } from './constants.stylex.js';

const styles = stylex.create({
container: {
padding: {
default: '4px'
[breakpoints.small]: '8px',
[breakpoints.medium]: '16px',
[breakpoints.large]: '24px',
},
},
label: {
color: colors.text,
},
});

positionTry

positionTry enables graceful fallback positioning via the @property-try at-rule. This makes it easier to handle layout edge cases across varying browser support and runtime constraints. (Thanks nmn!)

const fallback = stylex.positionTry({
positionAnchor: '--anchor',
top: '0',
left: '0',
width: '100px',
height: '100px',
});

const styles = stylex.create({
box: {
positionTryFallbacks: fallback,
},
});

Breaking changes

  • The attrs API is removed due to low usage and redundant functionality; non-React users can replace it with a wrapper around props as documented here.
  • The runtimeInjection compiler option is now disabled by default in development mode (dev:true) to better match production behavior.
  • ESLint rule no-legacy-conditional-styles is renamed to no-legacy-contextual-styles.
  • The config option useRemForFontSize is renamed to enableFontSizePxToRem; now disabled by default and not intended for external use.
  • The config option genConditionalClasses is renamed to enableInlinedConditionalMerge; now enabled by default and not intended for external use.

Fixes

  • Fixed duplicate classNames in styles with nested pseudo-classes (Thanks jeongminsang!)
  • ESLint plugin now correctly supports importSources object syntax in validImports (Thanks javascripter!)
  • Fixed a bug where CSS variables would be wrapped in quotes when used with the content property.
  • Fixed evaluation bug in firstThatWorks when the final value was a CSS variable.
  • Fixed TypeScript types for themes and types functions.

Miscellaneous

  • Rewrote the runtime style injection system to be more robust in dev. This resolves issues with hot reloading and duplicate style tags.
  • Added Flow types for anchor positioning. (Thanks Jta26!)
  • Added support for custom importSources in the PostCSS plugin for React Strict DOM compatibility. (Thanks javascripter!)
  • Improved compiler error messages.

Deprecations

We’ve deprecated the @stylexjs/shared package on npm.

· 2 min read
Melissa Liu

StyleX v0.12.0 introduces performance optimizations, several bug fixes, a new lint rule, and some cleanup of deprecated packages.

Performance

Object key minification

The keys of compiled style objects are now minified to reduce overall code size.

Faster theme compilation

Compiling createTheme calls is now several orders of magnitude faster. This was achieved by caching evaluated theme objects.

ESLint improvements

New no-legacy-contextual-styles rule

A new rule has been added to the StyleX ESLint plugin to flag uses of the deprecated media query and pseudo-class syntax. This rule flags usage of the legacy media query and pseudo-class syntax that wraps multiple property values inside a single @-rule or pseudo-class block. This pattern is deprecated and should be replaced with the updated syntax here. (Thanks vincentriemer!)

Bug fixes

Styling pseudo-elements in dynamic styles

Dynamic styles can now be used to style pseudo-elements. Previously, the generated CSS variables could not be inherited by pseudo-elements.

Disallow object spreads in create

Object spreading in create calls is now disallowed by the compiler, as this breaks runtime caching of style merging.

Deprecations

The following bundler integration packages have been deprecated. We're focusing development on the core StyleX toolchain, and providing consistent tools for use across different bundlers. We recommend using the @stylexjs/postcss-plugin.

  • @stylexjs/esbuild-plugin
  • @stylexjs/nextjs-plugin
  • @stylexjs/webpack-plugin

The @stylexjs/rollup-plugin remains, but may be generalized into an unplugin package to extend this option to other bundlers.

The following other packages have also been deprecated.

· 2 min read
Melissa Liu

Release Notes

StyleX v0.11.0 is now available, with significant improvements in debugging, CLI caching, and documentation!

111
Turn it up to v0.11.0!

Debugging Improvements

Improved Runtime Debugging

We've made some big improvements to the information available in debug mode. We now include sourceMap information to indicate the file and line of the create call responsible for providing styles on a given element. This information is contained in the data-style-src prop in the DOM. To use, set debug to true in the StyleX config. (Thanks necolas)

CLI Cache Improvements

The StyleX CLI now includes better cache invalidation and expanded support:

  • Cache now invalidates when config options change in the StyleX and .babelrc configurations
  • Added support for relative file paths
  • Now supports Deno applications

Documentation Updates

New theming recipes

We've added new documentation that provides improved guidance on theming, including best practices for resetting and merging themes, as well as dynamic color-scheme management using built-in functions. (Thanks nmn)

API enhancements

We've added documentation about the new PostCSS plugin and updated the docs to reflect the latest debug information. (Thanks necolas)

Miscellaneous

  • We've added exported return types for stylex.types.* functions such as stylex.Color and stylex.Length. Now, expressions like stylex.types.color("red") are explicitly typed as stylex.Color<string> (Thanks nmn)
  • We've added an autofix to the valid-styles rule to provide autofix suggestions for border styles
  • We've made a fix to how we process multivalue shorthands with slashes (Thanks yasuhiro-yamamoto)
  • Small typo fixes (Thanks mattstyles and necolas)

· One min read
Naman Goel

Release Notes

  • Fixed a bug where variables with camelCase names were incorrectly converted to kebab-case (Thanks yasuhiro-yamamoto)
  • Fixed a bug in the eslint valid-styles rule where it would incorrectly flag when importing a file with an extension (Thanks beaumontjonathan)
  • Added support for .js resolved file extension imports from .ts files (Thanks beaumontjonathan)
  • Replaced crypto with murmurhash for CLI caching
  • Fixed a bug where the import resolve function would not respect the Windows system (Thanks nonzzz)
  • Fixed a bug where the initial-value in @Property was invalid

· 3 min read
Naman Goel

Happy new year! We are excited to announce the release of StyleX v0.10.0, which includes several new features and improvements.

Easier adoption with the all-new PostCSS plugin

StyleX now ships with an all-new PostCSS plugin. This plugin allows you to use StyleX with any PostCSS-compatible toolchain, to better integrate with existing projects. The PostCSS plugin is now our recommended approach for using StyleX in a Next.js or Vite project. The example Next.js app in this repository has been updated to reflect this change. The existing @stylexjs/nextjs-plugin will be deprecated in the next release.

A huge thanks to javascripter for contributing this plugin.

Better debugging

StyleX has a new debug option to enable more readable classNames and variable names during development. With this option turned on, classNames will be prefixed with the affected CSS property and variables will be prefixed with their key name in your source code. (Thanks mellyeliu)

Additionally, the error messages of the StyleX Babel plugin have been improved to be more granular and correctly highlight the location of the source code causing the error.

ESLint improvements

All new no-unused rule

The StyleX ESLint plugin now ships with a new no-unused rule that detects unused styles. (Thanks Samantha-Zhan)

Other improvements

The valid-styles rule now offers more auto-fixes, and a small bug was fixed in the valid-shorthands rule. (Thanks mellyeliu)

Theming now works without manually configuring rootDir

StyleX previously required manual configuration of unstable_moduleResolution.rootDir for enabling the theming APIs. This is no longer the case. Additionally, compilation should be more reliable and cache-friendly, especially when using package managers like pnpm.

Performance improvements for Dynamic styles

StyleX uses CSS custom properties (aka CSS variables) as inline styles for dynamic values for styles. In v0.10.0 StyleX now generates @property declarations marking these variables as non-inheritable. This improves the style resolution performance of the browser's styling engine, which in some cases can be quite significant. We have also updated our benchmarks to track the code size impact of this change. (Thanks Samantha-Zhan)

CLI improvements

Caching

The StyleX CLI now uses a cache by default which ensures that only changed files are recompiled. This cache is stored in the nearest node_modules folder and works even without using watch mode. (Thanks mellyeliu)

Better interoperability

The CLI now supports configuring additional Babel presets and plugins that can run before the StyleX plugin to let you use custom syntax transformations. The StyleX Babel plugin was also updated to make this use-case more reliable.

Windows support

A bug with file paths was fixed and the CLI should now work correctly on Windows.

Documentation

We have introduced a new Recipes section in the documentation to showcase some useful patterns when using StyleX.

Miscellaneous

  • The StyleX Rollup plugin now supports generating filename hashes. (Thanks nonzzz)
  • We now use the @dual-bundle/import-meta-resolve package to replace esm-resolve which should making theming APIs more reliable. (Thanks p0nch000)
  • Removed unnecessary quotes around 'content' values in CSS files. (Thanks nikeee)
  • Added support for view-transition-name in ESLint's valid-styles rule.
  • Added support for interpolate-size in ESLint's valid-styles rule.

· 5 min read
Naman Goel

StyleX v0.9.3 is now available with some big improvements and bug-fixes.

Improvements to Theming APIs

There are some big improvements to the predictability and reliability of our theming APIs — defineVars and createTheme.

Breaking Change: Themes are now exclusive

When you create a VarGroup with defineVars, you are able to theme any subset of the variables within using the createTheme API. These themes can then be applied like any other StyleX styles using props (or attrs). If you try to apply multiple themes for the same VarGroup, on the same element, the last applied theme wins, just as you might expect.

However, previously, if you instead applied one theme on a parent element, and another theme on a child element, the themes would end up being merged.

// tokens.stylex.ts
import * as stylex from '@stylexjs/stylex';

export const varGroup = stylex.defineVars({
primary: 'black',
secondary: 'grey',
});
import * as stylex from '@stylexjs/stylex';
import {varGroup} from './tokens.stylex.ts';

const red = stylex.createTheme(varGroup, {
primary: 'red',
});

const blue = stylex.createTheme(varGroup, {
secondary: 'blue',
});

const styles = stylex.create({
primary: {color: varGroup.primary},
secondary: {color: varGroup.secondary},
});

function App() {
return (
<div {...stylex.props(red)}>
<div {...stylex.props(blue)}>
<span {...stylex.props(styles.primary)}>Hello </span>
<span {...stylex.props(styles.secondary)}>World!</span>
</div>
</div>
);
}

Previously this would have resulted in the text "Hello World!" being styled with a red primary color and a blue secondary color. Now, the text will be styled with a black primary color and a blue secondary color.

You can think of themes conceptually as re-applying the default values for any variables that are not explicitly overridden by the theme. This change simplifies the mental model for how themes work, and has the added benefit of making it easy to create "reset" themes:

const reset = stylex.createTheme(varGroup, {});
tip

You can define this "reset" theme multiple times within your app and they will all be de-duplicated by the compiler. We encourage you to "repeat yourself"!

rootDir is now optional!

Previously, when configuring the StyleX Babel plugin, you had to explicitly specify a rootDir value. Internally, this path was used to generate a canonical file path for every .stylex.js file in your project.

However, this was not only cumbersome, but it also resulted in errors when importing VarGroups from node_modules. Different package managers deal with packages differently, and this can be particularly consequential for mono-repos.

Now, the rootDir option is optional, and StyleX will use the nearest package.json file to determine the canonical path, automatically. This should make theming APIs work more reliably.

note

When determining the canonical path, StyleX will use the name field from the nearest package.json file and the relative path to the .stylex.js file. We intentionally ignore the version number.

This means that your project happens to contain multiple versions of the same package, StyleX will only generate a single set of variables for them. This will usually be the desired behavior, but you may see some unexpected results if the variables within the two versions are different.

We will be making further improvements to minimize any such edge-cases.

More reliable ESM resolution

The StyleX Babel plugin now uses the esm-resolve package to resolve ESM imports. This should fix most situations where the compiler would fail to resolve VarGroup imports in result in the compilation of create to fail.

Thanks hipstersmoothie!

Dynamic style improvements

Dynamic Styles within StyleX have been improved to be more reliable and efficient. Previously, if the dynamic value of a style resolved to null at runtime, StyleX would represent that with the revert keyword in CSS. This did not always work as expected, ran into certain browser bugs and resulted in styles that were unnecessarily bloated.

In v0.9.3, null values for Dynamic styles work exactly the same as using null as a static value within create. This means any previously applied value for the given property will be removed and no className will be applied for that property.

@stylexjs/dev-runtime overhaul

The @stylexjs/dev-runtime package is a development-only package that lets you use a much slower version of StyleX that runs entirely at runtime. Previously, it worked by patching the main @stylexjs/stylex package at runtime. However, this did not always work reliably.

Breaking Change: The @stylexjs/dev-runtime package now returns the StyleX API.

import makeStyleX from '@stylexjs/dev-runtime';

const stylex = makeStyleX({
// configuration options
classNamePrefix: 'x',
dev: true,
test: false,
});

const styles = stylex.create({
color: 'red',
});
danger

The @stylexjs/dev-runtime only exists as a convenience for development purposes. It does not completely match the behavior of the StyleX compiler and will always lack certain features.

DO NOT use it in production.

Improved handling of nested pseudo-elements and pseudo-classes

Fixed a bug where using Pseudo Classes (such as :hover) within Pseudo Elements (such as ::before) (or vice-versa) would sometimes result in surprising behavior. StyleX now handles such cases, with an arbitrary level of nesting, correctly.

Miscellaneous

  • Added support for additional Pseudo Elements and Pseudo Classes to our ESLint rule and type definitions.
  • Slightly better compiler error messages.