Benchmarks comparing build time, bundle size, and runtime performance of popular CSS-in-JS libraries against Mochi.css.
| Library | Description |
|---|---|
mochi-vanilla-react |
Mochi.css with @mochi-css/vanilla-react |
mochi-stitches |
Mochi.css with the Stitches.js adapter (@mochi-css/stitches) |
stitches |
@stitches/react (runtime CSS-in-JS) |
vanilla-extract |
@vanilla-extract/css (build-time CSS-in-JS) |
panda |
PandaCSS |
css-modules |
Plain CSS Modules |
A mock Mochi homepage with nine sections: Navbar, Hero, Stats, Features, CodeShowcase, ApiCarousel, ComponentExplorer, Cta, and Footer. Each section is styled using the library under test. The fixture is generated via codegen so all implementations are structurally equivalent.
| Metric | Description |
|---|---|
| Build time | Cold build with dist/ cleared. Libraries that require a codegen pre-step (Stitches, vanilla-extract, Panda) include that time. |
| JS bundle | Gzipped sum of all .js files in dist/assets/. Represents CSS-in-JS runtime overhead shipped to the browser. |
| CSS output | Gzipped sum of all .css files in dist/assets/. Stitches injects styles at runtime so its CSS output is 0. |
| FCP | First Contentful Paint — time until the browser renders first text or image. |
| TBT | Total Blocking Time — sum of main-thread blocking time between FCP and TTI. |
| CLS | Cumulative Layout Shift. |
All browser metrics are measured with Playwright (Chromium headless) using CDP throttling: Slow 4G (~1.6 Mbps, 150 ms RTT) + 8x CPU slowdown applied to localhost.
mochi-vanilla-react is the canonical, handwritten source implementation.
All other implementations are derived from it automatically so that every library renders structurally identical output.
codegen/index.ts reads the mochi-vanilla-react/src/ tree using SWC and produces a target-specific source tree for each library:
- Shared layout files (
App.tsx, section.tsxfiles,tokens.ts,main.tsx) are copied verbatim — the JSX structure and token values are identical across all implementations. - Style files (
.styled.tsfiles and component.tsxfiles) are parsed with SWC to extractstyled()andcss()calls including their full style objects. The extracted style data is then handed to a per-library generator that re-emits equivalent code using that library's API.
Each library has its own generator in codegen/generators/.
The generators translate the Mochi style objects into the target library's syntax (e.g., vanilla-extract's style(), Panda's css(), Stitches' styled()),
preserving property values, local CSS variables, token references, and animation imports.
To regenerate a specific implementation:
yarn workspace @mochi-css/benchmarks codegen # regenerates allOr for a single target:
cd tools/benchmarks && npx tsx codegen/index.ts stitchesAfter building all implementations, Playwright parity tests in tests/parity.spec.ts verify that every implementation produces the same output as mochi-vanilla-react:
- DOM parity: the full page DOM is normalized (class names, inline styles,
id, anddata-*attributes are stripped) and compared textually against themochi-vanilla-reactbaseline. Any structural divergence fails the test. - Screenshot parity: a full-page screenshot at 1280×900 is taken for each implementation and compared against a stored
baseline.png(captured frommochi-vanilla-react). A maximum of 2% pixel difference is allowed to account for subpixel rendering variation across platforms.
To run the parity tests (implementations must already be built and served on their respective ports):
yarn workspace @mochi-css/benchmarks testTo update the baseline screenshot after an intentional fixture change:
cd tools/benchmarks && npx playwright test --update-snapshots --grep "mochi-vanilla-react — baseline"Only pass
--update-snapshotstogether with--grep "mochi-vanilla-react — baseline". Without the grep filter, all implementations' screenshots would overwrite the baseline.
From the repo root:
yarn workspace @mochi-css/benchmarks benchmarkResults are written to results/latest.json and results/latest.md.
To regenerate just the Markdown report from an existing JSON result:
yarn workspace @mochi-css/benchmarks reportSee results/latest.md for the most recent run.