Developer preview. Vela, Facet, and Quire are pre-release and in active development — syntax, APIs, and availability may change, and they are not yet generally available.
SStretch Dev Docs
Facet

Utilities and Recipes

Authoring APIs that compile to the same FIR and de-duplicate to shared atoms.

Facet has three authoring surfaces.

1) Utility strings in markup

bg-action
fg-on-action
p-inset-md
hover:bg-action-hover
focus-visible:ring
@md:px-inset-lg
ps-inset-lg

Prefix order is flexible: one or more variants (hover, focus-visible, @md, etc.), then family-value, or a raw keyword.

Known utility families include:

  • bg, fg (color)
  • p, px, py, ps, pe, gap (spacing)
  • w, h, minw, maxw, minh, maxh
  • radius, text, weight, leading, shadow, bw, font
  • ring (flag)

Known states: hover, focus, focus-visible, focus-within, active, disabled.

Container keywords: @sm, @md, @lg (container-query breakpoints).

Arbitrary utility syntax uses brackets and uses _ as a space:

bg-[#ff0000]
p-[10px]

2) Typed fx() objects

Typed objects are lowered through the same FIR as utilities.

import { createAtomizer } from "facet";
const az = createAtomizer();
az.addFx({
  bg: "action",
  fg: "on-action",
  p: "inset.md",
  _hover: { bg: "action-hover" },
  _focusVisible: { ring: true },
  "@md": { px: "inset.lg" }
});

Arbitrary values are explicit and escaped:

{ fg: { raw: "#222222" }, p: { raw: "10px" } }

3) Recipes

Recipes let you define named variant combinations around typed objects.

import { defineRecipe, registerRecipe } from "facet";

const button = registerRecipe(az, defineRecipe({
  base: { _focusVisible: { ring: true } },
  variants: {
    tone: {
      primary: { bg: "action", fg: "on-action", _hover: { bg: "action-hover" } },
      subtle: { bg: "bg", fg: "ink-muted" },
    },
    size: {
      sm: { px: "inset.sm", py: "inset.md" },
      lg: { px: "inset.lg", py: "inset.md" },
    },
  },
  defaultVariants: { tone: "primary", size: "lg" },
}));

button.classesFor({ tone: "primary", size: "lg" });

Built output behavior

Utilities and fx() share vocabulary and token-to-FIR mapping, so identical declarations across surfaces compile to identical classes.

scanSource reads class strings and literal fx({...}) from raw source (.jsx/.vue/.svelte/.html), and reports non-static fx calls instead of silently dropping them.

Planned note

The source mentions parser breadth (comments and static extraction completeness) as a future production improvement area.