Compiled CSS-in-JS: Atlassian's compile-time styling library for React
A familiar and performant compile time CSS-in-JS library for React.
At a glance
- What is it?
- Compiled moves CSS-in-JS processing from runtime to build time by transforming styled and ClassNames calls into atomic CSS at compile time. It ships as separate npm packages for React, Webpack, Parcel, Babel and Vite, each maintained independently under the Apache-2.0 license.
- Who is it for?
- Compiled suits React projects where build-time CSS extraction matters: applications where runtime style injection is a performance cost, or build pipelines where atomic CSS output is easier to cache. It is not a match for projects that need dynamic styles computed from arbitrary runtime values, since extraction requires all style values to be statically analysable at compile time.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Compile-time means styles are resolved during the build, not in the browser
CSS-in-JS libraries divide into two categories by when they process style declarations. Runtime libraries ship style logic to the browser and compute class names during rendering. Compiled takes the opposite approach: a Babel plugin or a bundler loader analyses your JSX at build time, strips the inline style objects, and writes atomic CSS to a static file or inlines the class names directly.
Atomic CSS in this context means each unique property-value pair gets its own single-purpose class. A component with two properties produces two atomic classes rather than one compound rule. That format deduplicates across components: if two different components both set color: hotpink, both reference the same atomic class rather than generating two rules with the same content.
For a large application, that deduplication is where the build-time approach pays off. Runtime libraries generate new style entries on every mount unless you cache them explicitly. Compiled's output is fixed after the build, so the browser caches it once and subsequent navigations require no additional style parsing. There is no JavaScript CSS-in-JS runtime to download, parse and execute in the critical path.
Three APIs cover most React styling patterns: css prop, styled, and ClassNames
Compiled exports three main APIs from @compiled/react: the css prop on JSX elements, the styled factory for components, and ClassNames for situations where the caller controls how a class name is applied.
The css prop attaches styles directly to an element without a named component:
import { styled, ClassNames } from '@compiled/react';
<div css={{ color: 'purple' }} />styled follows the tagged template literal pattern familiar from libraries like styled-components, and it supports props-based interpolation:
const StyledButton = styled.button`
color: ${(props) => props.color};
`;ClassNames gives a css function to callers who need to pass a class name to a child component rather than applying it to a wrapper:
<ClassNames>
{({ css }) => children({ className: css({ fontSize: 12 }) })}
</ClassNames>All three go through the same compile-time transformation. What each API produces in the component source is replaced at build time by static class names and the corresponding atomic CSS rules. No style computation happens in the browser for any of the three.
Installing @compiled/react and wiring it to Webpack, Parcel, Babel or Vite
Start with the React package:
npm install @compiled/reactThat package alone does nothing without a build integration. Webpack users add the loader:
npm install @compiled/webpack-loader --save-devParcel users install the config package and extend from it in .parcelrc:
npm install @compiled/parcel-config --save-dev{
"extends": ["...", "@compiled/parcel-config"]
}For Babel as a standalone transform:
npm install @compiled/babel-plugin --save-devA separate @compiled/vite-plugin package exists (version 2.0.4 was released on 2026-09-17) for Vite-based projects, and examples/vite/ in the repository demonstrates that setup. An SSR example under examples/ssr/ shows server-side rendering with Compiled, though the README does not describe that configuration in prose.
Each of these integrations transforms Compiled's API calls into atomic CSS at build time, so the choice is entirely bundler-driven rather than style-driven. Documentation for each path lives at compiledcssinjs.com/docs/installation, and each bundler has its own dedicated section there.
CSS extraction strips the CC and CS runtime components from the output bundle
Without extraction, each component carries a thin runtime: the CC and CS helper components insert style tags as needed during rendering. With extraction enabled, the Webpack or Parcel integration removes those helpers and writes all styles to a static CSS file.
When extraction is active, a component that previously rendered CC and CS wrapper elements becomes a plain span or div with atomic class names, and the style rules go into the extracted sheet. The README shows the before and after for a component with font-size and color properties:
._1wybfyhu {
font-size: 48px;
}
._syaz1q9v {
color: hotpink;
}Extraction applies to components in the app and to components sourced through NPM, as long as those NPM packages were themselves compiled with the Compiled plugin. A dependency that is not compiled stays in its original form and continues inserting styles at runtime.
For SSR there is an examples/ssr/ directory in the repository. How the extracted CSS interacts with server-side rendering is documented at compiledcssinjs.com rather than in the README.
Static analysis at build time breaks when style values come from runtime data
Compiled's compile-time transformation requires that style values are statically analysable. When a style depends on a value that only exists at runtime, such as a colour read from a database, a user preference, or an arbitrary JavaScript expression, the compiler cannot produce a fixed atomic class for it.
Prop-based interpolation in the styled API works because Compiled generates a CSS variable for the interpolated value and a matching class that applies it. That pattern handles a defined prop interface. Styles that compose arbitrary objects at runtime fall outside what static analysis can resolve, and Compiled's output for those cases is not described in the README.
A related constraint involves conditional style objects. Patterns like css={{ ...(condition ? stylesA : stylesB) }} work when both branches are statically known objects in the same file. When the branches import style objects from external modules not processed by the Compiled plugin, the result depends on whether those modules were also compiled, which is not guaranteed for all dependencies.
Migration from emotion or styled-components is possible in many cases but involves auditing where runtime computation is used. Compiled's documentation covers migration guidance at compiledcssinjs.com, but the README does not describe which emotion or styled-components features are unsupported. Any migration should start with the project's own compatibility notes.
Atlassian Labs maintenance, Apache-2.0 license and independent package releases
Compiled is an Atlassian Labs project with Michael Dougall listed as author in package.json. Last push to the repository was on 2026-10-06. It is not archived.
Releases are published per package rather than as a single version for the whole project. Recent releases include @compiled/[email protected] on 2026-09-24, @compiled/[email protected] on 2026-09-17 and @compiled/[email protected] on 2026-09-17. CHANGELOG.md at the repository root is the place to track changes across packages.
Licensing is Apache-2.0. That is a permissive license and its compatibility with GPL-licensed projects is a common question; the license file at the repository root is the appropriate reference rather than this article.
For upgrade cost, the packages follow independent version numbers, so upgrading one package does not automatically require upgrading the others. Whether @compiled/[email protected] works with @compiled/[email protected] at an older version requires checking the compatibility notes in the individual package changelogs or at compiledcssinjs.com.
Emotion and styled-components as the closest alternatives, with different extraction models
Both emotion and styled-components are the most direct alternatives, as each provides styled and css prop APIs with similar ergonomics. Neither performs compile-time extraction by default: both inject styles at runtime via a style tag or CSSStyleSheet, which means style processing runs on each render cycle unless explicit caching is configured.
Emotion has a Babel plugin that can extract styles at build time, but extraction in emotion is not the default behaviour and requires explicit setup. Compiled makes extraction the central design goal rather than an opt-in mode, and the monorepo structure of the project shows that each bundler integration is maintained alongside the core package rather than as a separate community project.
Styled-components has no official build-time extraction comparable to Compiled. Runtime style injection is its documented behaviour, and while third-party tools attempt server-side extraction, those are unofficial.
For teams already using CSS Modules or utility-class approaches such as Tailwind CSS, Compiled occupies a different position: it offers the same co-location of styles and components that CSS-in-JS provides, but with a static output that avoids the runtime cost. The trade-off is a more constrained styling model where values must be statically knowable, unlike the fully dynamic approach that CSS Modules and Tailwind are designed around.
Editorial conclusion
Compiled suits React projects where build-time CSS extraction matters: applications where runtime style injection is a performance cost, or build pipelines where atomic CSS output is easier to cache. It is not a match for projects that need dynamic styles computed from arbitrary runtime values, since extraction requires all style values to be statically analysable at compile time. Before adopting it in a monorepo, read the @compiled/webpack-loader or @compiled/parcel-config documentation at compiledcssinjs.com to understand how extraction interacts with packages sourced through NPM.
Frequently asked questions
What is Compiled CSS-in-JS?
Compiled is a compile-time CSS-in-JS library for React maintained by Atlassian Labs. It transforms css prop, styled and ClassNames calls into atomic CSS classes at build time rather than at runtime.
How do I install Compiled in a React project?
Start with npm install @compiled/react, then add the integration for your bundler: @compiled/webpack-loader for Webpack, @compiled/parcel-config for Parcel, or @compiled/babel-plugin for Babel. A @compiled/vite-plugin package also exists.
Does Compiled support CSS extraction to a static file?
Yes. With extraction enabled through the Webpack or Parcel integration, Compiled strips the CC and CS runtime helpers from components and writes all atomic CSS rules to a static stylesheet. The extraction documentation is at compiledcssinjs.com/docs/css-extraction-webpack.
Can I migrate from styled-components or emotion to Compiled?
Compiled offers similar styled and css prop APIs, and migration documentation is available at compiledcssinjs.com. The README does not document which styled-components or emotion features are unsupported, so reading the project's migration notes directly is the starting point.
What license does Compiled use?
Apache-2.0, as stated in package.json and the LICENSE file at the repository root.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/atlassian-labs-compiled)