{"id":23256,"date":"2025-11-11T09:58:20","date_gmt":"2025-11-11T17:58:20","guid":{"rendered":"https:\/\/engineering.fb.com\/?p=23256"},"modified":"2025-11-14T10:04:02","modified_gmt":"2025-11-14T18:04:02","slug":"stylex-a-styling-library-for-css-at-scale","status":"publish","type":"post","link":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/","title":{"rendered":"StyleX: A Styling Library for CSS at Scale"},"content":{"rendered":"<p><a href=\"https:\/\/stylexjs.com\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">StyleX<\/span><\/a><span style=\"font-weight: 400;\"> is Meta\u2019s styling system for large-scale applications. It combines the ergonomics of CSS-in-JS with the performance of static CSS, generating collision-free atomic CSS while allowing for expressive, type-safe style authoring. <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">StyleX was open sourced<\/span><\/a><span style=\"font-weight: 400;\"> at the end of 2023 and has since become the standard styling system across Meta products like Facebook, Instagram, WhatsApp, Messenger, and Threads, as well as external companies like Figma and Snowflake.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">At its core, StyleX is a compiler that extracts styles at build time and generates a static stylesheet. But it\u2019s also a philosophy: a framework for authoring, sharing, and maintaining CSS at scale. StyleX makes styling intuitive for everyday engineers by imposing constraints that encourage predictability, enable composition, and scale effortlessly across teams and codebases.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">How Do We Build CSS at Scale?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">To understand the purpose of StyleX, let\u2019s look at the history of CSS at Meta. Serving CSS at such a scale resulted in collisions across bundles, difficulties in managing dependencies between stylesheets, and challenges in reconciling competing rules that frequently led to specificity wars. Engineers resorted to complex selectors and<\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\"> !important<\/span><span style=\"font-weight: 400;\"> tags, making styles brittle and hard to maintain. Large, monolithic CSS bundles meant browsers were downloading hundreds of kilobytes of unused rules on every page load, slowing rendering and interaction.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To address these issues, Facebook built <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">cx<\/span><span style=\"font-weight: 400;\">, a CSS-modules-like system that linked local CSS to JavaScript. <span style=\"font-weight: 400; font-family: 'courier new', courier; color: #008000;\">cx <\/span><\/span><span style=\"font-weight: 400;\">resolved issues with namespace collisions and dependency management but remained limited to static styles defined in separate files.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ ComponentName.css; class uses ComponentName\/namespace syntax\r\n.ComponentName\/header { margin-top: 10px }\r\n\r\n\/\/ ComponentName.js \r\n&lt;div className={cx('ComponentName\/header')} \/&gt;<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">When we <\/span><a href=\"https:\/\/engineering.fb.com\/2020\/05\/08\/web\/facebook-redesign\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">rebuilt Facebook.com<\/span><\/a><span style=\"font-weight: 400;\"> from the ground up, we had the opportunity to build something better. Around this time, the <\/span><a href=\"https:\/\/speakerdeck.com\/vjeux\/react-css-in-js\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">CSS-in-JS<\/span><\/a><span style=\"font-weight: 400;\"> movement was gaining momentum. Developers increasingly wanted to colocate styles with component code, write dynamic styles based on runtime state, and leverage JavaScript paradigms like import graphs, module scoping, and type systems. But early CSS-in-JS systems relied on runtime injection: dynamically generating <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">&lt;style&gt;<\/span><span style=\"font-weight: 400;\"> tags and mutating the DOM during render, patterns that introduced measurable performance overhead.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">import * as stylex from '@stylexjs\/stylex';\r\n\r\nconst styles = stylex.create({\r\n  foo: { margin: 10 }\r\n});\r\n\r\nfunction MyComponent({}) {\r\n  return &lt;div {...styles.props(styles.foo)}\/&gt;\r\n}\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">We built on the lessons of this movement and made a system that is CSS-in-JS only in form, with styles compiling to static CSS. StyleX soon replaced our precursor <span style=\"color: #339966;\">cx<\/span> <\/span><span style=\"font-weight: 400;\">system and transformed the way we approached styling. With StyleX, styles were now defined in JavaScript, enabling composition, conditional logic, and build-time compilation. Atomic classes reduced CSS size by 80% and made styling maintainable across a rapidly scaling codebase.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Today, StyleX is the default styling system at Meta, powering everything from product surfaces to component libraries. Engineers use it to build interfaces that are expressive, reusable, and performant.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Into the Compiler<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">The power of StyleX lies in its abstraction. We automatically handle CSS specificity, variable generation, and static compilation to generate predictable, collision-free atomic CSS. This avoids the maintenance overload of hand-authored CSS styles, allowing users to focus on style authoring.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">StyleX lives in a monorepo composed of several integrated packages. The core engine is a <\/span><a href=\"https:\/\/babel.dev\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Babel<\/span><\/a><span style=\"font-weight: 400;\"> plugin that runs a transform across a project and returns the extracted CSS. At a high level, <a href=\"https:\/\/github.com\/facebook\/stylex\/tree\/main\/packages\/%40stylexjs\/babel-plugin\" target=\"_blank\" rel=\"noopener\">the compiler<\/a> traverses a set of files, extracts CSS metadata from style objects, and converts style declarations to atomic CSS classes. The collected metadata is then run through several processes: value normalization, at-rules wrapping, and legacy polyfills. Finally, the CSS rules are sorted and outputted into a static sheet.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-23259\" src=\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png\" alt=\"\" width=\"1999\" height=\"955\" srcset=\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png 1999w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=916,438 916w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=768,367 768w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=1024,489 1024w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=1536,734 1536w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=96,46 96w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image1.png?resize=192,92 192w\" sizes=\"auto, (max-width: 992px) 100vw, 62vw\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s explore the behind-the-scenes of this process through the <a href=\"https:\/\/stylexjs.com\/docs\/learn\/thinking-in-stylex\/\" target=\"_blank\" rel=\"noopener\">values of StyleX<\/a>.\u00a0<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Scalability<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">At the heart of StyleX is its static compilation into <\/span><a href=\"https:\/\/compiledcssinjs.com\/docs\/atomic-css\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">atomic CSS<\/span><\/a><span style=\"font-weight: 400;\">. <\/span><span style=\"font-weight: 400;\">Styles are converted to classes containing a single style declaration for reuse across a codebase so CSS size plateaus as the application grows. Whenever possible, styles are compiled away and cached per file, so the system can analyze all reachable styles, deduplicate shared declarations, and emit only what\u2019s needed at runtime.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The core API surface is intentionally lightweight:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.create()<\/span><span style=\"font-weight: 400;\"> is used to define style objects. Objects are stripped away at build time and converted to atomic CSS. Each <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">property: value <\/span><span style=\"font-weight: 400;\">pair is hashed and outputted as a CSS class. This API is designed for cacheability and only allows for statically resolvable values. <\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">stylex.props()<\/span><span style=\"font-weight: 400;\"> handles merging and deduping of style objects. Each call is transpiled to an object containing a space-separated <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">className<\/span><span style=\"font-weight: 400;\"> string corresponding to each atomic style, and a <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">style<\/span><span style=\"font-weight: 400;\"> prop for dynamic styles. When styles are local to the module, we compile at build time; when styles are used across module boundaries, we defer to a tiny runtime merge.<\/span><\/li>\n<\/ul>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">import * as stylex from '@stylexjs\/stylex';\r\n\r\nconst styles = stylex.create({\r\n  foo: { margin: 10 }\r\n  bar: { margin: 10, color: 'red' }\r\n});\r\n\r\nfunction MyComponent({style}) {\r\n  return (\r\n    &lt;&gt;\r\n     &lt;div {...styles.props(styles.foo)}\/&gt; \r\n     &lt;div {...styles.props(styles.bar)}\/&gt; \r\n     &lt;div {...stylex.props(style)}\/&gt; \r\n    &lt;\/&gt;\r\n  )\r\n}\r\n<\/code><\/pre>\n<p>In each JavaScript file, API calls are replaced with the class names from the generated CSS and local styles are stripped away. The above component compiles to something like this:<\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">import * as stylex from '@stylexjs\/stylex';\r\n\r\nfunction MyComponent({style}) {\r\n  return (\r\n    &lt;&gt;\r\n     &lt;div className=\"m-10\" \/&gt;\r\n     &lt;div className=\"c-red m-10\" \/&gt; \r\n     &lt;div {...stylex.props(style)}\/&gt; \r\n    &lt;\/&gt;\r\n  )\r\n}\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">After the transform is run across files, we process the collected metadata, generate LTR\/RTL variants, resolve constants, and order CSS rules by priority. The output is a string that can be emitted as a static stylesheet and post-processed by any of our bundlers.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-css\">.m-10 { margin: 10px }\r\n.c-red { color: red }\r\n<\/code><\/pre>\n<h3><span style=\"font-weight: 400;\">Expressiveness<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">StyleX enforces constraints as design principles instead of limitations. We disallow conflict-prone patterns like <\/span><i><span style=\"font-weight: 400;\">styling at a distance<\/span><\/i><span style=\"font-weight: 400;\"> and enforce patterns that are statically resolvable. Within these boundaries, however, StyleX remains expressive. We\u2019ve designed for maximum flexibility within these constraints through the following <\/span><a href=\"https:\/\/stylexjs.com\/docs\/api\/\"><span style=\"font-weight: 400;\">APIs<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h4><span style=\"font-weight: 400;\">Shareable Values<\/span><\/h4>\n<p><span style=\"font-weight: 400;\"><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.create()<\/span>is designed for per-file cacheability: all CSS metadata must be derived solely from the JavaScript defined within that file. <\/span><span style=\"font-weight: 400;\">We use an extended version of Babel\u2019s <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">evaluate<\/span><span style=\"font-weight: 400;\"> function to resolve values. The compiler never needs to read the contents of imported modules to generate the stylesheet.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To enable reusable values across files, we provide APIs like <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.defineVars()<\/span><span style=\"font-weight: 400;\"> and <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">stylex.defineConsts()<\/span><span style=\"font-weight: 400;\">. These functions generate deterministic hashes based on variable name and import path that remain consistent across modules. This allows us to resolve variables anywhere they\u2019re imported without traversing the file that declares them. At build time, shared constants are fully inlined, while shared variables become global CSS custom properties that can be referenced across components.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">\/\/ varsFile.stylex.js\r\nconst varColors = stylex.defineVars({primary: \"#eee\"})\r\n\/\/ constsFile.stylex.js\r\nconst constColors = stylex.defineConsts({primary: \"#fff\"})\r\n\r\n\/\/ Component.react.js\r\nimport {varColors} from 'varsFile.stylex.js' \r\nimport {constColors} from 'constsFile.stylex.js' \r\n\r\nconst styles = stylex.create({\r\n    foo: {color: varColors.primary} \/\/ \u2192 .x { var(--hash('varsFile.varColors.primary')) }\r\n    bar: {color: constColors.primary} \/\/ \u2192 hash('constsFile.constColors.primary') \u2192 #fff\r\n  },\r\n});\r\n<\/code><\/pre>\n<h4 class=\"line-numbers\"><span style=\"font-weight: 400;\"><br \/>\nStyling at a Distance<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">As mentioned, StyleX is a system for styling components. Elements are styled using classnames. Global and complex selectors are disallowed to avoid styling at a distance: rules that affect elements indirectly from elsewhere in the DOM. Global baseline rules like element selectors or CSS resets must be defined in a separate stylesheet. This is to minimize indirect styling and promote <\/span><a href=\"https:\/\/stylexjs.com\/docs\/learn\/thinking-in-stylex\/#encapsulation\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">encapsulation<\/span><\/a><span style=\"font-weight: 400;\"> of styles.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-css\">\/* Unsafe: styles leak to child elements rather than being explicitly applied *\/\r\n.csuifyiu:hover &gt; div <span style=\"font-weight: 400;\">{ ... }<\/span>\r\n\r\n\/* Safe: styles are scoped to a specific element based on observed state *\/\r\ndiv:hover &gt; .ksghfhjsfg <span style=\"font-weight: 400;\">{ ... }<\/span> <\/code><\/pre>\n<p><span style=\"font-weight: 400;\">However, we do allow <\/span><i><span style=\"font-weight: 400;\">observing from a distance<\/span><\/i><span style=\"font-weight: 400;\"> using the <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">stylex.when<\/span><span style=\"font-weight: 400;\"> APIs. This API provides a suite of relational selectors to style a component based on the state of its ancestors, descendants, or siblings. Observed elements must be marked with <\/span><span style=\"font-weight: 400;\"><span style=\"font-family: 'courier new', courier; color: #339966;\">stylex.defaultMarker()<\/span><\/span><span style=\"font-weight: 400;\">, ensuring styles remain directly applied while supporting contextual behavior.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">const styles = stylex.create({\r\n    foo: {\r\n      backgroundColor: {\r\n        default: 'blue',\r\n        [stylex.when.ancestor(':hover')]: 'red',\r\n      },\r\n    },\r\n});\r\n\r\n&lt;div {...stylex.props(stylex.defaultMarker())}&gt;\r\n  &lt;div {...stylex.props(styles.foo)}&gt; Some Content &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<\/code><\/pre>\n<h4><span style=\"font-weight: 400;\">Preserving CSS Features<\/span><\/h4>\n<p><span style=\"font-weight: 400;\">StyleX preserves most of the CSS feature set (media queries, pseudoclasses, keyframes, and more) through static transforms at build time. Wherever possible, we mirror native CSS behavior so styling feels expansive and familiar.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">While StyleX is built around static compilation, it also supports dynamic styles. When a value isn\u2019t known at build time, the compiler emits a CSS variable reference, and the runtime writes it inline through the <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">style<\/span><span style=\"font-weight: 400;\"> prop.\u00a0<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">const styles = stylex.create({\r\n    \/\/ Height is unknown until runtime\r\n    foo: (height) =&gt; ({\r\n      height,\r\n    }),\r\n});\r\n\r\n\/\/ { .d-height {var(--height)}, style: {--height: height} }\r\n&lt;div {...stylex.props(styles.foo(height))}\/&gt; \r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">Theming APIs like <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.defineVars()<\/span><span style=\"font-weight: 400;\"> and <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.createTheme() <\/span><span style=\"font-weight: 400;\">allow users to create and mutate shareable design tokens. <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">defineVars()<\/span><span style=\"font-weight: 400;\"> creates a variable grouping, and <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">createTheme()<\/span><span style=\"font-weight: 400;\"> allows users to create variants by redefining variable groups at a higher specificity.<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-css\">\/* const spacing = stylex.defineVars({sm: 2px, md: 4px, lg: 8px}) *\/\r\n:root, .sp-group{--sp-sm:2px;--sp-md:4px;--sp-lg:8px;}\r\n\r\n\/* const desktopSpacing = stylex.createTheme(spacing, {sm: 5px, md: 10px, lg: 20px}) *\/\r\n.sp-dktp.sp-dktp, .sp-dktp.sp-dktp:root{--sp-sm:5px;--sp-md:10px;--sp-lg:20px;}\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.defineConsts()<\/span><span style=\"font-weight: 400;\"> allows users to define shareable constants and media queries without overloading browser memory with CSS variables. During compilation, StyleX gathers metadata across all <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">defineConsts()<\/span><span style=\"font-weight: 400;\"> calls, generates placeholder hashes in\u00a0 <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">create()<\/span><span style=\"font-weight: 400;\"> calls, and inlines the constant values directly into the generated stylesheet.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Finally, APIs like <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.keyframes()<\/span><span style=\"font-weight: 400;\"> and <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">stylex.viewTransitionClass()<\/span><span style=\"font-weight: 400;\"> support animations by generating <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">@keyframes<\/span><span style=\"font-weight: 400;\"> and <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">::view-transition-*<\/span><span style=\"font-weight: 400;\"> rules.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Predictability<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">StyleX is a system for styling components. We discourage global styling in favour of applying localized classnames on elements directly. Our design is centered around predictable style merging: The last style always wins! You can think of the <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">stylex.props <\/span><span style=\"font-weight: 400;\">function as a deterministic merge of style objects: given <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">stylex.props(styles.foo, styles.bar)<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">bar <\/span><span style=\"font-weight: 400;\">always overrides <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">foo<\/span><span style=\"font-weight: 400;\">. This makes it easy to share and combine styles predictably across files.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CSS specificity follows a hierarchy where selectors are assigned different priorities. The calculation is based on a three-column value of IDs, classes, and types, commonly written as, <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">(ID, Class, Type)<\/span><span style=\"font-weight: 400;\">. Because StyleX is entirely class-based, resolving conflicts between style objects means determining which class names to apply and enforcing priorities between them.\u00a0<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">const styles = stylex.create({\r\n  foo: { color: 'red', margin: 0 }\r\n  bar: { color: 'black', marginTop: 10 }\t\r\n});\r\n\r\nfunction MyComponent() {\r\n  \/\/ becomes &lt;div className=\"c-black m-0 mt-10\" \/&gt; \r\n  return &lt;div {...stylex.props(styles.foo, styles.bar)} \/&gt; \r\n}\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">During merge, repeated properties across style objects are deduplicated so that only the last value is applied. As a result, each class name in the DOM node corresponds to a single property. In the above example, the <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">color: red <\/span><span style=\"font-weight: 400;\">class is dropped during merge so <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">color: black <\/span><span style=\"font-weight: 400;\">takes precedence. But resolving overlaps between shorthands and constituent longhands is more complex.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Consider the following HTML:<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-html\">&lt;style&gt;\r\n  .margin-top-10 { margin-top: 10px }\r\n  .margin-0 { margin: 0px }\r\n&lt;style\/&gt;\r\n\r\n&lt;div className=\"margin-0 margin-top-10\" \/&gt;\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">When multiple classes are applied on a <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">div<\/span><span style=\"font-weight: 400;\">, the resulting styling is based solely on the specificity of the selectors (in this case, the order of the classes). Without additional handling, <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">margin<\/span><span style=\"font-weight: 400;\"> overrides <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">margin-top <\/span><span style=\"font-weight: 400;\">here completely! <\/span><\/p>\n<p><span style=\"font-weight: 400;\">Throw pseudoclasses and media queries in the mix and things become even more complex:<\/span><\/p>\n<pre class=\"line-numbers\"><code class=\"language-javascript\">{\r\n   [ \"m-0\", { \"css\": \".m-10 {margin: 0}\" }, 3000 ], \r\n   [ \"mt-10\", { \"css\": \".mt-10 {margin-top: 10px}\", }, 4000 ], \r\n   [ \"mt-10-mq\", { \"css\": \"@media (...) {.mt-10-mq {margin-top: 10px} }\", }, 4200 ], \r\n   [ \"mt-10-mq\", { \"css\": \"@media (...) {.mt-10-mq:hover {margin-top: 10px} }\", }, 4320 ], \r\n}\r\n<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">To handle this ambiguity, we compute a numerical <\/span><span style=\"font-weight: 400; color: #339966; font-family: 'courier new', courier;\">priority<\/span><span style=\"font-weight: 400;\"> alongside each CSS rule. We use these priorities alongside a user-configured <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">styleResolution<\/span><span style=\"font-weight: 400;\"> to determine the specificity of each class selector using the <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">@layer<\/span><span style=\"font-weight: 400;\"> at-rule or equivalent polyfill. <\/span><\/p>\n<p><span style=\"font-weight: 400;\">The enforced ordering looks something like this:\u00a0<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-23258\" src=\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png\" alt=\"\" width=\"1122\" height=\"368\" srcset=\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png 1122w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png?resize=916,300 916w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png?resize=768,252 768w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png?resize=1024,336 1024w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png?resize=96,31 96w, https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-image2.png?resize=192,63 192w\" sizes=\"auto, (max-width: 992px) 100vw, 62vw\" \/><\/p>\n<p><span style=\"font-weight: 400;\">The result? Longhands and shorthands merge predictably, <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">:active<\/span><span style=\"font-weight: 400;\"> states override <\/span><span style=\"font-weight: 400; font-family: 'courier new', courier; color: #339966;\">:hover<\/span><span style=\"font-weight: 400;\"> states, media queries override default behaviour, and user-authored order is respected when possible. This behind-the-scenes specificity handling allows developers to combine and reuse styles without manually resolving conflicts.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Looking Forward<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">StyleX is maintained by a team of CSS enthusiasts who aim to make styling accessible to everyone. Beyond the compiler, the monorepo includes an <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\/tree\/main\/packages\/%40stylexjs\/eslint-plugin\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">ESLint plugin<\/span><\/a><span style=\"font-weight: 400;\"> for style validation, a <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\/tree\/main\/packages\/%40stylexjs\/cli\"><span style=\"font-weight: 400;\">CLI<\/span><\/a><span style=\"font-weight: 400;\"> for easy stylesheet generation, a <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\/blob\/main\/packages\/%40stylexjs\/postcss-plugin\/README.md\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">PostCSS plugin<\/span><\/a><span style=\"font-weight: 400;\"> for post-processing, and an experimental <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\/tree\/main\/packages\/style-value-parser\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">CSS parser<\/span><\/a><span style=\"font-weight: 400;\">.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The open source community has played an important role in shaping the direction of StyleX, and been a massive force multiplier in our work. We continue to learn, grow, and ideate in collaboration with the companies and individuals adopting our work. Today, with the help of thousands of contributors, the ecosystem includes a community-built <\/span><a href=\"https:\/\/venerable-melomakarona-255f96.netlify.app\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">playground<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=yash-singh.stylex\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">VS Code extensions<\/span><\/a><span style=\"font-weight: 400;\">, an <\/span><a href=\"https:\/\/github.com\/Dwlad90\/stylex-swc-plugin\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">SWC compiler<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/www.npmjs.com\/package\/vite-plugin-stylex\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">multiple<\/span><\/a> <a href=\"https:\/\/github.com\/sukkaw\/stylex-webpack\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">bundler<\/span><\/a> <a href=\"https:\/\/www.npmjs.com\/package\/unplugin-stylex\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">integrations<\/span><\/a><span style=\"font-weight: 400;\">, and <\/span><a href=\"https:\/\/stylexjs.com\/docs\/learn\/ecosystem\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">more<\/span><\/a><span style=\"font-weight: 400;\">!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We\u2019re always exploring new ways to make StyleX the styling system for the modern web. Our work is an ongoing dialogue between the needs of the community and the values that guide our design. Roadmap highlights include an API for shareable functions, LLM-ready context files, support for inline styles, developer extensions, strict compiler validation, logical styles utilities, and an official unplugin for bundler integrations. Our goal is to continue to evolve alongside the browser and keep imagining what styling on the web can be.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Happy style authoring! We make StyleX for you.<\/span><\/p>\n<h2>Learn More<\/h2>\n<p><span style=\"font-weight: 400;\">To hear the latest on StyleX, check out the <\/span><a href=\"https:\/\/stylexjs.com\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">StyleX website<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/github.com\/facebook\/stylex\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">GitHub<\/span><\/a><span style=\"font-weight: 400;\">, <a href=\"https:\/\/bsky.app\/profile\/stylexjs.bsky.social\" target=\"_blank\" rel=\"noopener\">Bluesky<\/a> and <\/span><a href=\"https:\/\/x.com\/stylexjs\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">X<\/span><\/a><span style=\"font-weight: 400;\">.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To learn more about Meta Open Source, visit our <\/span><a href=\"https:\/\/opensource.fb.com\/\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">website<\/span><\/a><span style=\"font-weight: 400;\">, subscribe to our <\/span><a href=\"https:\/\/www.youtube.com\/channel\/UCCQY962PmHabTjaHv2wJzfQ\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">YouTube channel<\/span><\/a><span style=\"font-weight: 400;\">, or follow us on <\/span><a href=\"https:\/\/www.facebook.com\/MetaOpenSource\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Facebook<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/www.threads.net\/@metaopensource\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Threads<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/x.com\/MetaOpenSource\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">X<\/span><\/a><span style=\"font-weight: 400;\">, <\/span><a href=\"https:\/\/bsky.app\/profile\/metaopensource.bsky.social\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">Bluesky<\/span><\/a><span style=\"font-weight: 400;\"> and <\/span><a href=\"https:\/\/www.linkedin.com\/showcase\/meta-open-source?fbclid=IwZXh0bgNhZW0CMTEAAR2fEOJNb7zOi8rJeRvQry5sRxARpdL3OpS4sYLdC1_npkEy60gBS1ynXwQ_aem_mJUK6jEUApFTW75Emhtpqw\" target=\"_blank\" rel=\"noopener\"><span style=\"font-weight: 400;\">LinkedIn<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Acknowledgements<\/span><\/h2>\n<p><i><span style=\"font-weight: 400;\">Special thanks to past maintainers Naman Goel and Sebastian McKenzie; contributors Frank Yan, Jerry Su, Ankit Sardesai, Joel Austin, Daniel Neiter, Nicolas Gallagher, Vincent Riemer, Ezzudin Alkotob, Andrey Sukhachev, Nitish Mehrotra, Nadiia D., Prakshal Jain, JC P\u00e9rez Ch\u00e1vez, Samantha Zhan, Chang Yan, Tina Gao, Anay Bhakat; advisors Christopher Chedeau, Baraa Hamodi, Dennis Wilkins, Chris Callahan, Richard Hansen, Robert Maratos, Will Hastings, Ricky Li, Andrew Imm, Tim Yung, Eli White; Modern CSS leads; the Web Platform org; the open source community; and the lineage of systems like React Native and Linaria that continue to inspire our work.<\/span><\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>StyleX is Meta\u2019s styling system for large-scale applications. It combines the ergonomics of CSS-in-JS with the performance of static CSS, generating collision-free atomic CSS while allowing for expressive, type-safe style authoring. StyleX was open sourced at the end of 2023 and has since become the standard styling system across Meta products like Facebook, Instagram, WhatsApp, [&#8230;]<\/p>\n<p><a class=\"btn btn-secondary understrap-read-more-link\" href=\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\">Read More&#8230;<\/a><\/p>\n","protected":false},"author":51,"featured_media":23269,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[174,6],"tags":[],"class_list":["post-23256","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-open-source","category-web","fb_content_type-article"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v19.3 (Yoast SEO v19.12) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>StyleX: A Styling Library for CSS at Scale - Engineering at Meta<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Melissa Liu\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\"},\"author\":{\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#author\",\"name\":\"\"},\"headline\":\"StyleX: A Styling Library for CSS at Scale\",\"datePublished\":\"2025-11-11T17:58:20+00:00\",\"dateModified\":\"2025-11-14T18:04:02+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\"},\"wordCount\":1944,\"publisher\":{\"@id\":\"https:\/\/engineering.fb.com\/#organization\"},\"articleSection\":[\"Open Source\",\"Web\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\",\"url\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\",\"name\":\"StyleX: A Styling Library for CSS at Scale - Engineering at Meta\",\"isPartOf\":{\"@id\":\"https:\/\/engineering.fb.com\/#website\"},\"datePublished\":\"2025-11-11T17:58:20+00:00\",\"dateModified\":\"2025-11-14T18:04:02+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/engineering.fb.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"StyleX: A Styling Library for CSS at Scale\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/engineering.fb.com\/#website\",\"url\":\"https:\/\/engineering.fb.com\/\",\"name\":\"Engineering at Meta\",\"description\":\"Engineering at Meta Blog\",\"publisher\":{\"@id\":\"https:\/\/engineering.fb.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/engineering.fb.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/engineering.fb.com\/#organization\",\"name\":\"Meta\",\"url\":\"https:\/\/engineering.fb.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/engineering.fb.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2023\/08\/Meta_lockup_positive-primary_RGB.jpg\",\"contentUrl\":\"https:\/\/engineering.fb.com\/wp-content\/uploads\/2023\/08\/Meta_lockup_positive-primary_RGB.jpg\",\"width\":29011,\"height\":12501,\"caption\":\"Meta\"},\"image\":{\"@id\":\"https:\/\/engineering.fb.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Engineering\/\",\"https:\/\/twitter.com\/fb_engineering\"]},[]]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"StyleX: A Styling Library for CSS at Scale - Engineering at Meta","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/","twitter_misc":{"Written by":"Melissa Liu","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#article","isPartOf":{"@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/"},"author":{"@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#author","name":""},"headline":"StyleX: A Styling Library for CSS at Scale","datePublished":"2025-11-11T17:58:20+00:00","dateModified":"2025-11-14T18:04:02+00:00","mainEntityOfPage":{"@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/"},"wordCount":1944,"publisher":{"@id":"https:\/\/engineering.fb.com\/#organization"},"articleSection":["Open Source","Web"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/","url":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/","name":"StyleX: A Styling Library for CSS at Scale - Engineering at Meta","isPartOf":{"@id":"https:\/\/engineering.fb.com\/#website"},"datePublished":"2025-11-11T17:58:20+00:00","dateModified":"2025-11-14T18:04:02+00:00","breadcrumb":{"@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/engineering.fb.com\/2025\/11\/11\/web\/stylex-a-styling-library-for-css-at-scale\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/engineering.fb.com\/"},{"@type":"ListItem","position":2,"name":"StyleX: A Styling Library for CSS at Scale"}]},{"@type":"WebSite","@id":"https:\/\/engineering.fb.com\/#website","url":"https:\/\/engineering.fb.com\/","name":"Engineering at Meta","description":"Engineering at Meta Blog","publisher":{"@id":"https:\/\/engineering.fb.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/engineering.fb.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/engineering.fb.com\/#organization","name":"Meta","url":"https:\/\/engineering.fb.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/engineering.fb.com\/#\/schema\/logo\/image\/","url":"https:\/\/engineering.fb.com\/wp-content\/uploads\/2023\/08\/Meta_lockup_positive-primary_RGB.jpg","contentUrl":"https:\/\/engineering.fb.com\/wp-content\/uploads\/2023\/08\/Meta_lockup_positive-primary_RGB.jpg","width":29011,"height":12501,"caption":"Meta"},"image":{"@id":"https:\/\/engineering.fb.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Engineering\/","https:\/\/twitter.com\/fb_engineering"]},[]]}},"jetpack_featured_media_url":"https:\/\/engineering.fb.com\/wp-content\/uploads\/2025\/11\/Meta-StyleX-Thumbnail-Final.png","jetpack_shortlink":"https:\/\/wp.me\/pa0Lhq-636","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/posts\/23256","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/users\/51"}],"replies":[{"embeddable":true,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/comments?post=23256"}],"version-history":[{"count":32,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/posts\/23256\/revisions"}],"predecessor-version":[{"id":23301,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/posts\/23256\/revisions\/23301"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/media\/23269"}],"wp:attachment":[{"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/media?parent=23256"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/categories?post=23256"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/engineering.fb.com\/wp-json\/wp\/v2\/tags?post=23256"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}