INTRODUCTION
Introduction
What Plumeria is, what your styles compile to, and why none of the library ships.
Plumeria is a React styling library. You write style objects in TypeScript, and the compiler turns them into atomic CSS and rewrites every call site, so no library code reaches your JavaScript bundle and no style is computed in the browser.
Which value wins is never left to stylesheet order. Styles merge property by property and the one on the right wins, whether it comes from the same file, another module, or a parent through a prop, so splitting and moving files never changes what renders. A mistake stops the build at the line that caused it.
Write a style
Define styles with css.create() and attach them with the sx prop:
import * as css from '@plumeria/core';
const styles = css.create({
text: {
padding: 16,
color: 'gray',
},
});
export const Footer = () => <p sx={styles.text}>MyText</p>;The import and the css.create() call compile away, and the declarations move to a generated stylesheet:
export const Footer = () => <p className={"xqqbxt1d xuifcaas"}>MyText</p>;.xqqbxt1d { padding: 16px; }
.xuifcaas { color: gray; }Compose from the right
sx accepts arrays, ternaries and conditions. When two styles set the same property, the one on the right wins:
import * as css from '@plumeria/core';
const styles = css.create({
base: {
padding: 16,
color: 'gray',
},
active: {
color: 'teal',
},
});
export const Item = ({ isActive }: { isActive: boolean }) => (
<p sx={[styles.base, isActive && styles.active]}>MyText</p>
);The class that loses never reaches the element:
<p class="xqqbxt1d xuifcaas">MyText</p> <!-- isActive is false -->
<p class="xqqbxt1d xxcejlqg">MyText</p> <!-- isActive is true -->A shorthand against a longhand is the exception: the longhand wins wherever the two meet, in either order. Specificity ranks every pair, and Composition laws states the merge formally.
Share across files
Styles compile to zero across file boundaries too, so you can keep them beside a component or share them, whichever fits the project:
import * as css from '@plumeria/core';
export const styles = css.create({
common: {
color: 'gray',
},
});import { styles } from './styles';
export const Component = () => {
return <p sx={styles.common}>Shared style</p>;
};A file that applies them with sx needs nothing else. A file that passes them to a component through any other prop imports @plumeria/core, which is how the compiler finds it; importing it in every file that uses Plumeria is always safe and keeps each file on the fastest path.
Types all the way down
Plumeria treats a style as a type schema, not a runtime object. Every entry point of the package is a .d.ts file, so there is no JavaScript to import:
{
"name": "@plumeria/core",
"exports": {
".": {
"types": "./lib/css.d.ts"
},
"./sx": {
"types": "./lib/sx.d.ts"
}
}
}Static styles resolve to class names entirely at compile time. The dynamic pieces leave no library behind either: function keys compile down to CSS variables, and a style chosen at runtime compiles to a literal lookup of precomputed class strings. What ships is class names, CSS, and the expressions you already wrote:
- No runtime bundle
- No runtime evaluation
- No runtime parsing
- No runtime dependencies
Zero-runtime means the cost moves, not that it vanishes. All of the work happens at build time, and the browser receives class names and CSS.
Ask an agent to write Plumeria
Copy this prompt into your coding agent:
Build this with Plumeria for all styling. First read https://plumeria.dev/docs/installation and https://plumeria.dev/docs/ai in full, and follow every rule in the ai doc exactly — including the property order and the border shorthand expansion. If the project is not set up yet, set it up the way the installation doc describes. Task: <describe what to build>. Build with `npm run build` and lint with `npm run lint`; both must pass.Measured November 2026: with this prompt, a coding agent passed build + lint on the first try in 100 of 100 runs (20 tasks × 5 runs). Protocol and per-run results: Agent benchmark.
Next steps
This site is built with Plumeria. The documentation app lives in the same repository and depends on the workspace packages, so every release and every experiment runs here before it ships.