Skip to main content

Release 0.17.1

· 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!)