-
Public Repository Warning: This is a PUBLIC repository. Never include internal/sensitive information in the project.
-
File Operations:
- Always read files before editing them
- Always prefer editing existing files instead of creating new ones
- Always use specialized tools (read_files, edit, write) instead of bash commands where possible
- Never create documentation files unless directed
-
Communication Style:
- Always be concise and technical
- Always output text directly to user, NOT via bash echo or comments
- Always request more information when necessary
- Never use emoji
-
Code Quality:
- Always run relevant tests for the area of code being modified
- Always improve the test suite when fixing issues instead of just reading the code or using CLI
- Always format files after editing using the relevant tool
- Never use placeholders in code, always use real values or ask for them
-
Git Safety:
- Never push or commit unless directed
- Never update git config
- Never force push to main/master
- Never use interactive git commands (
-iflag) - Never skip hooks (--no-verify, --no-gpg-sign)
- Never run destructive git commands unless directed
- Never create PRs unless directed
-
Task Management:
- Always use the todo/task tool
- Always mark todos/tasks as complete immediately after finishing them
- Never work on multiple todos/tasks simultaneously
-
When stuck:
- Check existing documentation
- Ask the developer for clarification
- Review recent commits for context
Compiled is a compile-time CSS-in-JS library for React that transforms styled components into atomic CSS at build time via Babel AST transformations. Unlike runtime CSS-in-JS libraries, all styles are extracted and processed during compilation.
Core principle: Zero runtime CSS generation. All styles are determined at build time through static analysis and AST manipulation.
Yarn workspaces monorepo with three main workspace types:
packages/*- Core libraries published to npmexamples/*- Example integrations (webpack, parcel, ssr)fixtures/*- Test fixtures and babel component examples
Critical packages:
packages/babel-plugin/- Core Babel transformation engine (AST processing)packages/react/- Runtime library withax,ix,CC,CSutilitiespackages/css/- CSS parsing, sorting, and atomic stylesheet generationpackages/webpack-loader/,packages/parcel-transformer/- Bundler integrationspackages/babel-plugin-strip-runtime/- Extracts styles to separate.compiled.cssfilespackages/codemods/- Migration tools (emotion→compiled, styled-components→compiled)packages/eslint-plugin/- ESLint rules for enforcing Compiled best practicespackages/jest/- Jest testing utilities and matcherspackages/utils/- Shared utilities across packagespackages/benchmark/- Performance benchmarking tools
Uses TypeScript with ttsc (TypeScript Transformer Compiler) instead of plain tsc:
# Build order matters - babel fixtures first, then browser/cjs/esm
yarn build:babel-fixture # Compile test fixtures
yarn build:cjs # CommonJS output (packages/tsconfig.json)
yarn build:esm # ES modules (packages/tsconfig.esm.json)
yarn build:browser # Browser bundles (packages/tsconfig.browser.json)Post-build: scripts/postbuild.sh removes __tests__/ and __perf__/ from dist.
Key concept: One CSS rule per declaration. Class names encode both the atomic group (property+selectors+media) and value.
Format: _{group}{value} where group is 4 chars and value is 4+ chars (e.g., _1wyb1fwx for font-size:12px). The underscore + 4-char group makes ATOMIC_GROUP_LENGTH = 5 in code.
Runtime utilities (packages/react/src/runtime/):
ax()- Merges classnames, ensures last atomic group wins (handles composition)ac()- Advanced merging with AtomicGroups (chainable, memoized)ix()- Injects CSS variables for dynamic valuesCC,CS- Components for style sheet injection
Auto-ordering: Pseudo-classes sorted to prevent cascade issues (:link → :visited → :focus-within → :focus → :hover → :active)
Main exports from @compiled/react:
styled- Create styled components (e.g.,styled.div({ color: 'red' }))css- Define styles for css prop (e.g.,css({ color: 'red' }))cssMap- Create CSS maps for conditional stylingClassNames- Render prop component for dynamic className generationkeyframes- Define CSS animationsxcss/cx()- Strict-typed CSS system (Atlassian design system integration)createStrictAPI()- Create type-safe CSS APIs with restricted properties
See packages/react/src/index.ts for all exports.
yarn install # Install + postinstall.sh (sets up tooling)
yarn start # Storybook on :6006 (watch babel-plugin changes)
yarn test <filter> --watch # Run specific tests
yarn test:cover # Coverage report
yarn test:vr # Visual regression tests with Loki (requires Storybook running)
yarn benchmark # Run performance benchmarks
yarn lint # Run ESLint
yarn prettier:check # Check code formattingUnit tests:
- Test files:
packages/*/src/**/*.test.{ts,tsx} - Perf tests:
__perf__/*.test.ts - Use
transform()helper fromtest-utils.tsfor Babel plugin tests - Babel plugin tests check transformed output with
.toMatchInlineSnapshot() - Use
toHaveCompiledCss()matcher from@compiled/jest
Visual regression tests:
- Uses Loki with Storybook
- Run
yarn test:vr(requiresyarn startrunning in another terminal) - Accept changes with
yarn test:vr approve
Performance tests:
- Benchmark files in
__perf__/directories - Run with
yarn benchmark
Essential tool: astexplorer.net - Use Babel 7 parser to visualize AST
Key transformation flow:
- Parse JSX/TSX with Babel (
@babel/parser) - Traverse AST to find Compiled imports (
styled,css,cssMap,ClassNames,keyframes) buildCss()- Extract styles from expressions (objects/template literals)transformCssItems()- Convert to atomic CSS rulesbuildStyledComponent()/buildCompiledComponent()- Generate runtime codeappendRuntimeImports()- Add necessary runtime imports (ax,ix,CC,CS)
Common utilities (packages/babel-plugin/src/utils/):
css-builders.ts-buildCss()main entry pointbuild-styled-component.ts- GeneratesforwardRefcomponentstransform-css-items.ts- Converts styles to sheet/classname pairsast.ts- AST manipulation helpers
Two-phase transformation:
@compiled/babel-plugin- Transform CSS-in-JS to runtime code@compiled/babel-plugin-strip-runtime- Extract styles to.compiled.css
Configure in .babelrc:
{
"plugins": [
["@compiled/babel-plugin"],
[
"@compiled/babel-plugin-strip-runtime",
{
"extractStylesToDirectory": { "source": "src", "dest": "dist" }
}
]
]
}Important: Add "sideEffects": ["**/*.compiled.css"] to package.json to prevent tree-shaking.
yarn changeset # Create changeset (select minor/patch)
yarn release # Build + publish (CI only)minorfor new features,patchfor bug fixes- Changesets live in
.changeset/directory
Default import sources: @compiled/react (configurable via importSources option)
Supports custom import sources for Atlassian internal packages.
Babel plugin uses synchronous resolver (via enhanced-resolve) to statically evaluate imports. Custom resolvers configurable via plugin options.
Dynamic values injected as CSS variables:
// Input
<div css={{ color: props.color }} />
// Output
<div
style={{ "--_xyz": props.color }}
className="_abc123"
/>
// CSS: ._abc123 { color: var(--_xyz); }- Test files:
*.test.ts(not*.spec.ts) - Perf tests:
__perf__/*.test.ts - Fixtures:
__fixtures__/directories - Parcel-specific tests:
*.parceltest.ts
- ESLint:
@compiled/eslint-pluginprovides 12+ rules for best practices- Recommended config:
plugin:@compiled/recommended - Key rules:
no-css-tagged-template-expression,no-js-xcss,shorthand-property-sorting
- Recommended config:
- Prettier: Enforced via
yarn prettier:check/yarn prettier:fix - TypeScript: Strict mode enabled, uses
ttscfor custom transformers - Pre-commit hooks: Auto-runs lint and prettier via Husky
Styles injected in ordered buckets for cascade control:
- Default rules
- Link pseudo-selectors (
:link,:visited) - Focus pseudo-selectors (
:focus-within,:focus,:focus-visible) - Interaction pseudo-selectors (
:hover,:active) - At-rules (media queries - sorted mobile-first)
See packages/react/src/runtime/style.tsx for bucket implementation.
- Double transformation: Don't use both webpack-loader AND babel-plugin in babel config
- AST type confusion: Use
t.isIdentifier()etc. before accessing node properties - Test snapshots: Update with
--updateSnapshotflag, not manual edits - Babel config in tests: Always set
babelrc: false, configFile: falseto prevent inheritance - Atomic class deduplication: Remember
ax()uses last-wins strategy for same atomic group - xcss without TypeScript: The xcss prop requires TypeScript - use ESLint rule
@compiled/no-js-xcssto enforce - CSS extraction side effects: Must add
"sideEffects": ["**/*.compiled.css"]to package.json
Run specific example apps:
yarn start:webpack # Webpack dev server
yarn start:parcel # Parcel dev server
yarn start:ssr # SSR example
yarn build:webpack:extract # Test CSS extraction- Core transformation:
packages/babel-plugin/src/babel-plugin.ts - Runtime utilities:
packages/react/src/runtime/ - All exports:
packages/react/src/index.ts - Atomic CSS sorting:
packages/css/src/plugins/sort-atomic-style-sheet.ts - Test patterns:
packages/babel-plugin/src/__tests__/index.test.ts - ESLint rules:
packages/eslint-plugin/src/rules/ - Contributing guide:
CONTRIBUTING.md(includes AST resources) - Documentation website:
website/directory
- AST Explorer - Visualize Babel AST (use Babel 7 parser)
- Babel Handbook - Learn Babel plugin development
- Documentation website - User-facing docs and guides
- Storybook examples:
stories/directory - Live examples of all features