Ship Atomic CSS with StyleX
Build a React app and inspect StyleX atomic CSS in a production build.
Introduction
30 Second Summary
Visual styles often get copied from one part of an app to another. As the interface grows, those repeated choices can pile up behind the scenes.
In this project, you will style two React components with StyleX. You will compare the familiar style objects you write with the atomic CSS sent to the browser.
What You'll Build
You'll demo a Vite-powered app whose two components share one compiled style rule across the browser view and production CSS.
By the end of this project, you'll have:
- A styled two-component app you can run locally to see StyleX rules applied in the browser.
- Clear browser evidence showing short atomic class names in place of the style names you wrote.
- A production CSS file you can inspect to confirm repeated properties use a shared class.
- Secret Mission: An optional challenge to push your skills further.
Are there any prerequisites?
You need Node.js installed with its package manager available. Basic familiarity with React components is enough for this local project.
Before We Start
StyleX turns ordinary style objects into browser-ready CSS during the build. That workflow depends on a local JavaScript runtime.
This step prepares your local development toolkit. You will verify each tool through an observable check.
In this step, get ready to:
- Prepare Visual Studio Code for editing project files.
- Install the Node.js runtime with its included npm package manager.
- Confirm Chrome DevTools can inspect a page.
Set up your editor and terminal
A code editor keeps your project files together. These instructions use Visual Studio Code.
- Press Cmd+Space on macOS or the Windows key on Windows to open system search.
- Type Visual Studio Code in the search field.
✔️ Visual Studio Code appears
- Press Enter to open Visual Studio Code.
Visual Studio Code opens to its welcome screen. Your editor is ready for the project files you create next.
ⓧ Visual Studio Code is missing
Visual Studio Code is free to download. Choose the instructions for your operating system.
macOS
- Visit the official Visual Studio Code download page.
- Download the Universal option from the .dmg row.
- Open the downloaded .dmg file.
- Drag Visual Studio Code.app into the Applications folder.
- Press Cmd+Space to open system search.
- Type Visual Studio Code in the search field.
- Press Enter to open Visual Studio Code.
Windows
- Visit the official Visual Studio Code download page.
- Select the User Installer for your processor.
- Run the downloaded installer.
- Follow the installer prompts using the default options.
- Press the Windows key to open system search.
- Type Visual Studio Code in the search field.
- Press Enter to open Visual Studio Code.
Visual Studio Code includes an integrated terminal. This keeps your commands beside the files they affect.
- Click Terminal in the top menu.
- Select New Terminal.
You should see a terminal panel at the bottom of Visual Studio Code. Your editor can now run project commands.
Install Node.js with npm
Node.js runs JavaScript on your computer. npm installs the packages used by the project.
Why does one installation prepare both tools?
The Node.js installer includes npm. Installing the LTS release prepares the runtime plus its package manager.
Before you check, do you expect two version numbers or a missing-command message?
- Check your current installation by running these commands:
node --version
npm --version
What do these checks prove?
- The node command prints the installed Node.js version.
- The npm command prints the installed package manager version.
✔️ I see two version numbers
Both commands can reach their installed programs. Your JavaScript runtime is ready to create the app.
ⓧ I see a missing-command message
The LTS release is the stable choice for this project. Its installer includes npm.
- Visit the official Node.js download page.
- Select the LTS release.
- Download the installer for your operating system.
- Run the downloaded installer.
- Approve the operating system permission request if it appears.
- Accept the default installation options.
- Close the integrated terminal after installation finishes.
- Select New Terminal from the Terminal menu.
Before you recheck, do you expect both commands to reach the tools now?
- Verify the completed installation by running both checks again:
node --version
npm --version
Why use a fresh terminal?
A fresh terminal reloads the command path updated by the installer. Both tools should now be available from Visual Studio Code.
You should see one version number for Node.js. The next line should contain an npm version number.
Still missing a command?
- Close every terminal panel before creating a fresh one.
- Confirm that you installed the LTS release from the official Node.js download page.
- Restart your computer if the installer finished but the commands remain unavailable.
- Help me diagnose my Node.js installation.
Confirm your browser tools
The browser shows your finished interface. Chrome DevTools exposes the page structure plus the compiled styles behind it.
These instructions use Google Chrome so the inspection panels match what you see.
- Press Cmd+Space on macOS or the Windows key on Windows to open system search.
- Type Google Chrome in the search field.
✔️ Google Chrome appears
- Press Enter to open Google Chrome.
Your browser is ready for the local app you build next.
ⓧ Google Chrome is missing
Google Chrome includes the DevTools panels used throughout this project.
- Visit the official Google Chrome download page.
- Download the installer offered for your operating system.
- Run the downloaded installer.
- Approve the operating system permission request if it appears.
- Return to system search after the installation finishes.
- Type Google Chrome in the search field.
- Press Enter to open Google Chrome.
Before you inspect anything, which part of the page do you expect DevTools to highlight?
- Return to this NextWork project page in Google Chrome.
- Right-click a visible paragraph on the page.
- Select Inspect from the context menu.
You should see Chrome DevTools with the Elements panel selected. The highlighted HTML should correspond to the paragraph you inspected.
DevTools did not open?
- Confirm that the project page is open in Google Chrome.
- Right-click the paragraph itself before selecting Inspect.
- Press Cmd+Option+C on macOS or Ctrl+Shift+C on Windows to open the Elements panel directly.
- Help me open Chrome DevTools.
Your local toolkit is ready. Next, you will create the React app and load its first page.
Create the StyleX React App
Your StyleX styles need a build pipeline that can turn style objects into atomic CSS. A plain React starter provides the app shell without that compiler connection.
You'll scaffold the React app with Vite. The configured build pipeline ends with the starter page running in your browser.
In this step, get ready to:
- Create a Vite React project named stylex-atomic-css.
- Install StyleX with its Vite-compatible build plugin.
- Configure the plugin and run the starter app.
Scaffold the React project
Vite creates the folders and starter files that a React app needs. Starting on your Desktop keeps the new project easy to find.
- Move to your Desktop by running this command:
cd ~/Desktop
What does this command do?
The cd command changes the terminal's current location to your Desktop. Vite creates the project folder there.
- Approve the temporary package download if npm asks for permission.
- Create the stylex-atomic-css project from the React template by running this command:
npm create vite@latest stylex-atomic-css -- --template react
What does this command create?
- The project name becomes the stylex-atomic-css folder on your Desktop.
- The React template creates src/App.jsx, src/main.jsx, src/index.css, and vite.config.js.
- The generated package.json defines the project scripts and initial dependencies.
The terminal confirms that the project scaffold was created. Your next command installs the generated dependencies inside that folder.
- Enter the project folder and install its dependencies by running these commands:
cd stylex-atomic-css
npm install
What do these commands do?
- The first command moves the terminal into the new stylex-atomic-css folder.
- The second command downloads the packages listed in package.json.
The installation finishes with a dependency summary. The project now has the React and Vite packages needed to run locally.
Did the project installation fail?
- Check that your terminal is inside the stylex-atomic-css folder before retrying the installation.
- Check your internet connection if npm reports a download or registry problem.
- Follow npm's upgrade guidance if the terminal reports that your installed Node.js version is unsupported.
- Help me diagnose my Vite project installation error.
- Press Cmd+Space on macOS or the Windows key on Windows to open your operating system's search bar.
- Type the name of your code editor into the search bar.
You'll see your code editor in the search results.
- Press Enter to launch your code editor.
You'll see the editor's welcome screen.
- Choose your editor's folder-opening option.
- Select the stylex-atomic-css folder from your Desktop.
The editor's file sidebar now lists package.json, the src/ folder, and vite.config.js. This confirms that the scaffolded project is open.
Install and configure StyleX
The StyleX runtime lets your components use StyleX APIs. The Vite-compatible build plugin compiles those styles and adds the generated CSS to Vite's CSS output.
Why use the StyleX unplugin?
The unplugin connects StyleX directly to Vite's build process. This keeps the style transformation inside the same pipeline that already handles your React app.
The StyleX plugin runs before the React plugin to preserve Fast Refresh. Your browser can then reflect component updates during development.
- Install the StyleX runtime and its build plugin by running these commands in the project terminal:
npm install --save @stylexjs/stylex
npm install --save-dev @stylexjs/unplugin
What do these packages do?
- The @stylexjs/stylex package provides the APIs that your components use to define and apply styles.
- The @stylexjs/unplugin package connects the StyleX compiler to Vite.
- The install commands record both packages in package.json.
The terminal prints an updated dependency summary. StyleX and its build plugin are now part of the project.
Did the StyleX installation fail?
- Confirm the terminal path ends with stylex-atomic-css.
- Retry after restoring your internet connection if npm reports a package download problem.
- Help me fix my StyleX package installation.
- Open package.json from your editor's file sidebar.
You'll see React and Vite in the generated manifest. You'll also see @stylexjs/stylex and @stylexjs/unplugin from the installation you just completed.
- Open vite.config.js from your editor's file sidebar.
- Replace the file's contents with this configuration:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import stylex from '@stylexjs/unplugin'
// Compile StyleX before React preserves Fast Refresh during development
export default defineConfig({
plugins: [stylex.vite({ useCSSLayers: true }), react()],
})
What does this configuration do?
- The stylex import makes the Vite adapter available inside the configuration.
- The stylex.vite() call enables StyleX compilation during development and production builds.
- The useCSSLayers option wraps generated styles in CSS layers.
- Placing stylex.vite() before react() preserves React's Fast Refresh behavior.
- Save vite.config.js.
✔️ Configuration saved
Your vite.config.js now loads the StyleX plugin before the React plugin.
ⓧ I'd like to double check the full code
Compare your complete vite.config.js with this file:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import stylex from '@stylexjs/unplugin'
// Compile StyleX before React preserves Fast Refresh during development
export default defineConfig({
plugins: [stylex.vite({ useCSSLayers: true }), react()],
})
The plugin order is the key detail. StyleX appears first inside the plugins array.
Run the starter app
Starting the development server checks that Vite can load the new plugin configuration. A successful startup proves that the compiler connection is valid.
Before you run the server, do you expect the StyleX configuration to compile cleanly?
- Start the Vite development server by running this command:
npm run dev
What does this command do?
The dev script starts Vite with the plugins from vite.config.js. The terminal stays occupied while the development server is running.
You'll see a local address in the terminal without a configuration error. That address points to your running React app.
Did the development server stop?
- Confirm vite.config.js imports @stylexjs/unplugin with the exact package name.
- Confirm stylex.vite() appears before react() in the plugin list.
- Confirm the terminal is still inside the stylex-atomic-css folder.
- Help me debug my Vite development server.
Before you load the local address, what do you think the browser displays?
- Open the local address printed by the terminal in your browser.
You'll see the starter React page from the Vite template. Great work. Your app now runs through a build pipeline that includes StyleX.
- Leave the development server running in the terminal.
Does the browser stay blank?
- Confirm the terminal still shows the development server as active.
- Reload the local address shown by your latest server startup.
- Check the terminal for a configuration error if the browser cannot connect.
- Help me diagnose my blank Vite starter page.
Your StyleX build pipeline is ready. Next up, you'll replace the starter content with your first styled component.
Style Your First Component
The starter React page is already running through Vite. The project now needs a component that proves the styling pipeline works.
StyleX is connected to the build pipeline. In this step, you will give the compiler a style object and see its properties appear in the browser.
In this step, get ready to:
- Define the first component in src/App.jsx.
- Create its StyleX rules with stylex.create.
- Apply those rules with stylex.props.
Build the first styled component
stylex.create groups source rules under a local name. stylex.props turns that named group into props that React can spread onto an element.
- Select src/App.jsx from the file sidebar in your code editor.
- Replace the starter content by pasting this code:
import * as stylex from '@stylexjs/stylex';
// Define source rules that StyleX compiles into atomic CSS
const styles = stylex.create({
card: {
backgroundColor: 'blue',
color: 'white',
padding: '1rem',
},
});
function WelcomeCard() {
// Spread the generated props onto the rendered element
return (
<section {...stylex.props(styles.card)}>
<h1>Atomic CSS starts here</h1>
<p>This card is styled with StyleX.</p>
</section>
);
}
function App() {
// Render the styled card as the app's visible output
return <WelcomeCard />;
}
export default App;
How does this style flow work?
- The import makes the StyleX functions available inside src/App.jsx.
- stylex.create defines the source rules that the compiler transforms.
- styles.card identifies the rules for the card.
- stylex.props(styles.card) returns the props applied to the rendered section.
- Save src/App.jsx.
- Return to the browser tab running your local app.
You should see a blue card with white text. The text should have clear space around it.
That is your first StyleX component working in the browser.
Still seeing the starter page?
- Confirm that you saved src/App.jsx after replacing its contents.
- Check that the import path is exactly @stylexjs/stylex.
- Compare the braces around stylex.create with the complete file below.
- Help me debug why my StyleX card is missing or unstyled.
✔️ Awesome, I've got everything!
Your card is visible with its StyleX properties applied. Double check that src/App.jsx is saved.
ⓧ I'd like to double check the full code
Compare your src/App.jsx file with this complete version.
import * as stylex from '@stylexjs/stylex';
// Define source rules that StyleX compiles into atomic CSS
const styles = stylex.create({
card: {
backgroundColor: 'blue',
color: 'white',
padding: '1rem',
},
});
function WelcomeCard() {
// Spread the generated props onto the rendered element
return (
<section {...stylex.props(styles.card)}>
<h1>Atomic CSS starts here</h1>
<p>This card is styled with StyleX.</p>
</section>
);
}
function App() {
// Render the styled card as the app's visible output
return <WelcomeCard />;
}
export default App;
Verify the browser result
Before the final check, picture which visual properties you expect to remain after a manual refresh.
- Refresh the local app page in your browser.
You should still see the blue card with white text. You should also see space between the card edge and its content.
Your first StyleX component now has visible styling. Next, you will inspect the element to see what the compiler delivered to the browser.
Inspect the Atomic Classes
Your first component is now visibly styled with StyleX. The browser has received the compiled result.
This step reveals what that compilation produced. You'll use browser developer tools to connect the readable source in src/App.jsx to its Atomic CSS output.
In this step, get ready to:
- Select the first styled component in the browser's developer tools.
- Read the generated classes attached to the selected element.
- Compare the browser output with the authored styles in src/App.jsx.
Select the styled element
The Elements panel shows the live DOM that the browser rendered. Selecting the component connects the visible design to its HTML node.
- Switch back to the local app in the browser from earlier.
- Right-click directly on the first styled component.
- Select Inspect from the context menu.
Good. You should see the matching HTML node highlighted in the Elements panel.
What Does the Elements Panel Show?
The DOM tree shows the HTML currently rendered on the page. The selected opening tag contains the attributes delivered to the browser.
This view connects your component's visible result to the markup produced by the build process.
Trace the generated class names
A StyleX style object stays readable in your source code. The compiler translates its declarations into small classes before browser rendering.
Before you compare the two views, do you expect the browser to keep the names from your style object? Hold that prediction in mind.
- Read the class attribute on the highlighted opening tag in the Elements panel.
- Switch back to src/App.jsx in the code editor from earlier.
- Locate the style object passed to stylex.create.
- Compare its property names with the names in the selected element's class attribute.
- Return to the Elements panel in the browser's developer tools.
- Keep the first component selected for the checkpoint.
You'll see short StyleX-generated class names in the class attribute. The property names you authored stay in src/App.jsx.
Why Are the Class Names Short?
Atomic CSS gives each class one narrow styling job. StyleX can reuse the same class wherever the same declaration appears.
Your source object keeps the styling intent readable. The browser receives compact classes.
Can't Find the Generated Classes?
- Confirm the highlighted node matches the component with the visible StyleX styling.
- Expand the highlighted opening tag if its attributes are clipped.
- Select the styled component again if the Elements panel highlighted a surrounding element.
- Help me find the StyleX-generated class names in the Elements panel.
You've traced your readable StyleX source to its generated browser classes. Next, you'll add a second component to test whether the same atomic class appears again.
Reuse Styles in a Second Component
The first component has already shown that StyleX turns authored style declarations into short generated classes. One rendered element cannot show whether those classes are reusable.
A second React component instance gives you a direct comparison. Matching declarations should point both rendered elements to the same generated classes.
In this step, get ready to:
- Render a second instance of the existing styled component.
- Compare the generated classes on both rendered elements.
- Confirm that matching styles reuse the same class.
Render the component a second time
Two instances of the same component use the same StyleX declarations. This creates two visible elements without changing the styles you tested earlier.
- Switch back to the src/App.jsx tab in your code editor.
- Place your cursor after the existing component's JSX line inside the return block of App.
- Duplicate the entire JSX line directly below the original line.
- Save src/App.jsx.
Your local app updates after the save. You should see a second copy of the styled component beneath the first copy.
Only see one component?
- Confirm that the component-rendering line appears twice inside the return block of App.
- Check that the second line includes the complete opening tag plus its closing syntax.
- Save src/App.jsx again if your editor shows unsaved changes.
- Help me find why my React component only renders once.
✔️ Awesome, I've got everything!
Good work. Your app now renders two component instances from the same StyleX declarations.
ⓧ I'd like to double check the full code
Compare src/App.jsx with these checkpoints. This step changes only the rendered JSX inside App.
- Keep the existing StyleX import unchanged.
- Keep the existing StyleX style object unchanged.
- Keep the existing styled component definition unchanged.
- Confirm that the return block in App contains two identical component-rendering lines in succession.
Compare the generated classes
Browser DevTools now contains two DOM nodes created from the same component definition. Their class lists reveal whether StyleX generated a duplicate or reused the existing classes.
- Return to the Elements panel from earlier.
- Select the root element for the first rendered component.
- Choose one short generated class from its class list.
- Record that class here: one generated class from the first component.
Before you select the second component, do you expect a new class or the class you just recorded?
- Select the root element for the second rendered component.
- Scan its class list for one generated class from the first component.
You found it. Both rendered elements reference the same generated class for the matching style declaration.
Why does one class appear twice?
Atomic CSS assigns a reusable generated class to an individual style declaration. Matching declarations can reference that class wherever the style appears.
Both component instances point to one shared rule. Repeated styles therefore add class references without adding duplicate CSS rules.
Your app now demonstrates class reuse across two rendered components. Next, you will build the production app and inspect the generated CSS file.
Build and Review the CSS
Your two components now share a generated class for matching properties. That browser evidence shows StyleX reusing atomic CSS across components.
Development output can differ from the files a browser receives in production. The Vite build exposes the final CSS so you can judge the compiler's output directly.
In this step, get ready to:
- Create a production build of the app.
- Inspect the generated CSS asset for reused atomic rules.
- Record the generated CSS size for future comparisons.
Build the production assets
Your configured StyleX plugin turns the style objects into production CSS during the build. Vite writes the finished assets into the dist/ folder.
- Create a second terminal panel in the code editor.
- Predict whether the repeated property will appear once or twice in the final CSS.
- Create the production assets by running this command in the second terminal:
npm run build
What does this command do?
- The npm command runs the build script from package.json.
- Vite compiles the app into production assets inside dist/.
- The StyleX build plugin extracts the component styles into the generated CSS asset.
- Refresh the code editor's file sidebar to reveal the build output.
- Expand the dist/ folder.
- Expand the dist/assets/ folder.
You should see the build finish without errors. The terminal output includes a CSS asset inside dist/assets/ with its generated size.
Build not completing?
- Confirm the second terminal is inside the stylex-atomic-css folder.
- Check that vite.config.js still contains the StyleX build-plugin configuration from earlier.
- Review the first build error because it usually points to the file that stopped compilation.
- Help me diagnose my failed StyleX production build.
Review the generated atomic rules
The build summary proves that Vite created the production files. The generated stylesheet shows how StyleX represented your component styles.
- Open the generated file ending in .css inside dist/assets/.
- Scan the stylesheet from beginning to end.
- Identify the compact rules created for the two styled components.
You should see a small set of atomic rules in the generated stylesheet. Repeated property-value pairs are represented by shared rules instead of separate copies for each component.
What makes these rules atomic?
Each atomic rule represents a small styling decision that can be reused wherever the same value appears. Reuse keeps repeated component styles from producing repeated CSS.
The style objects remain readable in src/App.jsx. The browser receives compact generated classes backed by the extracted rules.
Can't find a generated CSS file?
- Confirm the production build completed without an error.
- Refresh the file sidebar after the build finishes.
- Verify that the StyleX build-plugin configuration remains enabled in vite.config.js.
- Help me find the missing StyleX CSS asset.
Record the CSS size
The generated asset size gives you a baseline for comparing StyleX with another styling approach. The shared class gives you direct evidence that repeated styles were emitted once.
- Predict whether the class shared by both components will have one matching selector or multiple matching selectors in the production CSS.
- Switch back to the browser DevTools from earlier.
- Record one generated class shared by both components here: your shared atomic class name.
- Return to the second terminal panel.
- Record the size shown for the generated CSS asset here: your generated CSS size.
- Switch back to the generated CSS file.
- Search the stylesheet for your shared atomic class name.
- Count the matching selector definitions in the generated stylesheet.
You should find one matching selector definition for the class used by both components. The terminal row provides the CSS size you can use as your comparison baseline.
That's the compiler proof: your production stylesheet contains the shared atomic rule once. You now have its size saved for your next styling comparison.
Secret mission
Audit One Shared Atomic Rule
Your two components already share atomic styles. Trace one repeated browser class to its declaration. Prove the production stylesheet emits that shared declaration only once.
Clean Up Your Resources
Clean Up Your Resources
Everything you built with StyleX runs locally with no ongoing costs. Use the options below to keep, pause, or delete your local resources.
Resources you used:
- The stylex-atomic-css project folder.
- The recorded generated CSS size note.
- The Vite development server process, if it is still running.
Keep everything running
No action is needed. Choose this option if you are still comparing the generated atomic classes or extending the app.
- Keep src/App.jsx as your two-component StyleX example.
- Keep vite.config.js as your working build-plugin reference.
- Keep dist/assets/ so you can revisit the generated production CSS.
- Keep your recorded CSS size for comparisons with other styling approaches.
- Leave the development server running only while you are actively inspecting the app.
Pause - I'll come back to this later
Stop the development server to free up your terminal while preserving every project file for later.
- Press Ctrl+C in the terminal where the development server is running.
- Close the browser tab showing the development app.
- Leave the stylex-atomic-css folder unchanged.
- Keep the recorded CSS size note for your next comparison.
- Return to the existing project folder when you are ready to continue.
Delete - I don't want to use this again
Deleting a project can feel final. Your system may keep it recoverable until you remove it permanently.
- Press Ctrl+C in the terminal if the development server is still running.
- Use the folder context menu in your code editor to show stylex-atomic-css in Finder on macOS or File Explorer on Windows.
- Close the project in your code editor.
- Delete the stylex-atomic-css folder from the file manager window, including the dist/ production build.
- Delete the recorded CSS size note from its saved location if you stored it outside the project folder.
At this point, your computer may still hold the deleted resources in its deleted-items location.
- Permanently remove the stylex-atomic-css folder from your system's deleted-items location.
- Permanently remove the CSS size note there if it appears separately.
- Search the folder's former parent directory for stylex-atomic-css.
- Check the location where you stored the CSS size note.
You should see no stylex-atomic-css folder. You should also see no separate CSS size note.
Nice Work!
Nice Work!
You did it! Your React app now proves how StyleX turns familiar style objects into shared atomic CSS. You also have a production build with a recorded CSS size for future comparisons.
You've learned how to:
- Render two React components with StyleX style objects applied correctly in the browser.
- Use your browser's developer tools to connect short atomic class names with the style objects you wrote.
- Confirm that repeated properties reuse a shared atomic rule in the generated production CSS.
- Take on an optional Secret Mission to push your atomic CSS skills further.
Ready to quiz yourself?