Plumeria

Plumeria 21.2

refirst11
refirst11Plumeria Core
Anionix
AnionixPlumeria Core

Plumeria v21.2 lets a package share Plumeria definitions. An app reads the css.createStatic values, styles and keyframes a package exports as it reads its own modules, and @plumeria/wind, the Tailwind CSS design tokens as a package, is the first one built this way.

1. Definitions from a package

Until now the compiler read definitions only from the app's own files. A package opts in by pointing a plumeria condition at its TypeScript source:

package.json
{
  "name": "@acme/tokens",
  "exports": {
    ".": {
      "plumeria": "./src/index.ts",
      "types": "./src/index.ts"
    }
  }
}
src/index.ts
import * as css from '@plumeria/core';

export const brand = css.createStatic({
  primary: '#0b5fff',
});

An app that lists the package in its dependencies reads it like a local module:

Button.tsx
import * as css from '@plumeria/core';
import { brand } from '@acme/tokens';

const styles = css.create({
  button: {
    backgroundColor: brand.primary,
  },
});

The compiler follows the plumeria condition, including subpath and pattern exports such as @acme/tokens/colors, and packages linked from a pnpm store. dependencies, devDependencies, peerDependencies and optionalDependencies all count. A package without the condition is not read.

An import whose names are all compiled away is now removed from the output, so the bundler never resolves @acme/tokens here. A package that exports only definitions can ship its source alone. One that also exports runtime code keeps a default condition for it, and an import still read at runtime, rendered as a component or re-exported stays in place.

2. @plumeria/wind

@plumeria/wind provides the Tailwind CSS v4.3.3 design tokens as css.createStatic values: the color palettes, spacing, type scale, font weights, radius, shadows, easing, breakpoints and animations.

npm i -D @plumeria/wind
Button.tsx
import * as css from '@plumeria/core';
import { blue, radius, slate, spacing, text } from '@plumeria/wind';

const styles = css.create({
  button: {
    paddingInline: spacing[4],
    fontSize: text.sm,
    color: slate[50],
    backgroundColor: blue[600],
    borderRadius: radius.md,
  },
});

It is built the way section 1 describes: its package.json points a plumeria condition at src/index.ts, and there is no build output. Every value is compiled into the styles that read it and the import is removed, so nothing from the package reaches the bundle. It generates no utility classes. The full list is in @plumeria/wind.

3. Namespace imports

21.0 made a namespace read of a definition a compile error. A read by name now compiles as a named import does:

import * as css from '@plumeria/core';
import * as tokens from './tokens';

const styles = css.create({
  link: { color: tokens.blue[500] },
});

tokens.blue is read as import { blue }, and the namespace import is removed when nothing else uses it. A string key, destructuring, a rest element or passing tokens as a whole still stops the build and asks for a named import.

4. Lint

no-combinator checks only the css.createStatic values that start with : or [, the ones that become a selector when used as a key. A value with spaces, such as a shadow or a font stack, is no longer reported. no-unknown-css-properties accepts fit-tolerance, min-size and max-size.

Upgrading

A module imported only for its definitions is no longer loaded through that import. If it also runs code on import, such as importing a global stylesheet, import it for its side effects as well:

import './tokens';

Release notes

21.2.0 (Oct 30, 2026)

  • Feat: a package can share its Plumeria definitions as source: when its exports point a plumeria condition at its TypeScript files, as in "plumeria": "./src/index.ts", an app that lists it in its dependencies reads the definitions it exports, such as css.createStatic values, css.create styles and css.keyframes names, as it reads a local module, including subpath and pattern exports and packages linked from a pnpm store
  • Feat: @plumeria/wind provides the Tailwind CSS v4.3.3 design tokens, such as the color palettes, spacing, type scale, radius, shadows and animations, as css.createStatic values; each value is compiled into the styles that read it, so the package adds nothing to the bundle
  • Feat: a definition read by name through a namespace import, such as tokens.blue[500] after import * as tokens from './tokens', compiles as it does through import { blue }; a string key, destructuring, a rest element or the namespace passed as a whole still stops the build and asks for a named import
  • Fix: an import whose names are all compiled away, such as a css.createStatic import read only inside css.create, is removed from the output, so the bundler no longer resolves or loads that module; an import still read at runtime, rendered as a component or re-exported is kept
  • Fix: reading a module's exports before the first project scan, as resolveExport and resolveExportValue can, no longer leaves that module out of the scan
  • Fix: no-combinator checks only the css.createStatic values that start with : or [, the ones that become a selector when used as a key, so a value with spaces, such as a shadow or a font stack, is no longer reported
  • Update: no-unknown-css-properties accepts fit-tolerance, min-size and max-size, from the latest MDN and webref data

On this page