Installation
Runtime
All uses of StyleX require the runtime package to be installed.
npm install --save @stylexjs/stylex
Compiler
The recommended way to use StyleX in development and production is with the build-time compiler.
Development
For development, you need only to configure the Babel plugin so that styles are processed at compile-time. The plugin will compile styles and insert runtime style injection code into your JavaScript modules.
npm install --save-dev @stylexjs/babel-plugin
// babel.config.js
import styleXPlugin from '@stylexjs/babel-plugin';
const config = {
plugins: [
[
styleXPlugin,
{
dev: true,
// Set this to true for snapshot testing
// default: false
test: false,
// Required for CSS variable support
unstable_moduleResolution: {
// type: 'commonJS' | 'haste'
// default: 'commonJS'
type: 'commonJS',
// The absolute path to the root directory of your project
rootDir: __dirname,
},
},
],
],
};
export default config;
Production
Production use of StyleX should extract CSS to an external file. This can be
done with any bundler that supports Babel, using the metadata generated by the
StyleX plugin. See the API reference for more details on the
@stylexjs/babel-plugin
API.
To make this easier for commonly used packages and meta-frameworks, StyleX provides (experimental) plugins for Webpack, Rollup, Next.js and esbuild.
Rollup
npm install --save-dev @stylexjs/rollup-plugin
import stylexPlugin from '@stylexjs/rollup-plugin';
const config = {
input: './index.js',
output: {
file: './.build/bundle.js',
format: 'es',
},
// Ensure that the stylex plugin is used before Babel
plugins: [stylexPlugin({
// Required. File path for the generated CSS file.
fileName: './.build/stylex.css',
// default: false
dev: false,
// prefix for all generated classNames
classNamePrefix: 'x',
// Required for CSS variable support
unstable_moduleResolution: {
// type: 'commonJS' | 'haste'
// default: 'commonJS'
type: 'commonJS',
// The absolute path to the root directory of your project
rootDir: __dirname,
},
})],
};
export default config;
Webpack
npm install --save-dev @stylexjs/webpack-plugin
const StylexPlugin = require('@stylexjs/webpack-plugin');
const path = require('path');
const config = (env, argv) => ({
entry: {
main: './src/index.js',
},
output: {
path: path.resolve(__dirname, '.build'),
filename: '[name].js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
],
},
plugins: [
// Ensure that the stylex plugin is used before Babel
new StylexPlugin({
filename: 'styles.[contenthash].css',
// get webpack mode and set value for dev
dev: argv.mode === 'development',
// Use statically generated CSS files and not runtime injected CSS.
// Even in development.
runtimeInjection: false,
// optional. default: 'x'
classNamePrefix: 'x',
// Required for CSS variable support
unstable_moduleResolution: {
// type: 'commonJS' | 'haste'
// default: 'commonJS'
type: 'commonJS',
// The absolute path to the root directory of your project
rootDir: __dirname,
},
}),
],
cache: true,
});
module.exports = config;
Next.js
npm install --save-dev @stylexjs/nextjs-plugin @stylexjs/babel-plugin rimraf
{
"scripts": {
...,
"predev": "rimraf .next",
"prebuild": "rimraf .next"
}
}
module.exports = {
presets: ["next/babel"],
plugins: [
[
"@stylexjs/babel-plugin",
{
dev: process.env.NODE_ENV === "development",
test: process.env.NODE_ENV === "test",
runtimeInjection: false,
genConditionalClasses: true,
treeshakeCompensation: true,
unstable_moduleResolution: {
type: "commonJS",
rootDir: __dirname,
},
},
],
],
};
/** @type {import('next').NextConfig} */
import stylexPlugin from "@stylexjs/nextjs-plugin";
const nextConfig = {};
const __dirname = new URL(".", import.meta.url).pathname;
export default stylexPlugin({
rootDir: __dirname,
})(nextConfig);
esbuild
npm install --save-dev @stylexjs/esbuild-plugin
import esbuild from 'esbuild';
import stylexPlugin from '@stylexjs/esbuild-plugin';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
esbuild.build({
entryPoints: ['src/index.js'],
bundle: true,
outfile: './build/bundle.js',
minify: true,
plugins: [
stylexPlugin({
// If set to 'true', bundler will inject styles in-line
// Do not use in production
dev: false,
// Required. File path for the generated CSS file
generatedCSSFileName: path.resolve(__dirname, 'build/stylex.css'),
// Aliases for StyleX package imports
// default: '@stylexjs/stylex'
stylexImports: ['@stylexjs/stylex'],
// Required for CSS variable support
unstable_moduleResolution: {
// type: 'commonJS' | 'haste'
// default: 'commonJS'
type: 'commonJS',
// The absolute path to the root of your project
rootDir: __dirname,
},
}),
],
})
Please refer to the StyleX examples apps for demonstrations on how to use each of these plugins.
Local development only
You should not use @stylexjs/dev-runtime
in production. It has a significant
performance cost and should only be used for local development without a
compiler. This runtime lacks features otherwise available when using the
compiler.
To start using StyleX without having to configure a compiler and build process, you can install the local development runtime.
npm install --save-dev @stylexjs/dev-runtime
The development runtime must be imported in your app's JavaScript entry-point and configured.
import inject from '@stylexjs/dev-runtime';
inject({
classNamePrefix: 'x',
dev: true,
test: false,
});
Once this is done, you can import and use @stylexjs/stylex
without any further
setup until you're ready to deploy to production.
Catch mistakes with ESLint
The StyleX compiler does not validate your styles and will compile many invalid styles. You should use the ESLint plugin to catch these mistakes when you author your styles.
npm install --save-dev @stylexjs/eslint-plugin
module.exports = {
plugins: ["@stylexjs"],
rules: {
"@stylexjs/valid-styles": "error",
},
};