bakeware License Build status npm
- Utility functions for vanilla-extract
- TypeScript-ready, with built-in type definitions
- Supports type scale and vertical rhythm out of the box
- normalize helper suited for 2026 usage
- Access custom property values from themes
- Manage breakpoints with ease
npm install bakeware
Generates a space-separated string of values, following CSS conventions.
| Description | Default | |
|---|---|---|
values |
A list of numbers or strings. | — |
options.baseValue |
Base value used to calculate the spacing units. | 1rem |
options.ratio |
A ratio of the base value used as a spacing unit. | 1/4 |
options.separator |
Character used to separate the fragments—" " or ",". |
" " |
import { spacing } from "bakeware"; spacing(1, 2); // "0.25rem 0.5rem" spacing(1, 2, { ratio: 2 }); // "0.5rem 1rem" spacing(1, 2, { baseValue: "16px" }); // "4px 8px" // Comma-separated declarations `translate3d(${spacing(1, 2, 3, { separator: "," })})`; // "translate3d(0.25rem,0.5rem,0.75rem)"
Creates a vertical rhythm system based on a given signature.
| Description | Default | |
|---|---|---|
signature |
An object { lineHeight, spacingRatio } or a string in the format "${number}/${number}". |
— |
options.typeScale |
typeScale configuration—when set, the returned object includes a fontSize method. |
undefined |
options.whitespaceRatio |
Minimum whitespace between the line height and the actual text, expressed as a ratio between 0 and 1. |
0 |
import { verticalRhythm } from "bakeware"; const { spacing } = verticalRhythm({ lineHeight: 1.5, spacingRatio: 1/4 }); spacing(1, 2); // "0.375rem 0.75rem"
import { verticalRhythm } from "bakeware"; const { spacing } = verticalRhythm("4/6"); spacing(1, 2); // "0.375rem 0.75rem"
import { verticalRhythm } from "bakeware"; const { fontSize, spacing } = verticalRhythm("2/3", { typeScale: "geometrical.goldenRatio", whitespaceRatio: 0.2, }); spacing(1, 2); // "0.75rem 1.5rem" fontSize(0); // { fontSize: "1rem", lineHeight: "1.5rem" } fontSize(1); // { fontSize: "1.618033988749895rem", lineHeight: "3rem" } fontSize(2); // { fontSize: "2.618033988749895rem", lineHeight: "4.5rem" }
Generates a type scale based on mathematical or geometric formulas.
| Description | Default | |
|---|---|---|
scale |
A string path (e.g., "natural.majorSecond") or a number representing the ratio. |
— |
unit |
The CSS unit to use for the resulting font size. | "rem" |
import { typeScale } from "bakeware"; const { fontSize } = typeScale("natural.majorSecond"); fontSize(0); // "1rem" fontSize(1); // "1.125rem" fontSize(2); // "1.265625rem"
CSS normalization based on Normalize.css and recent discussions across the web. It focuses on minimal impact, resetting only the styles strictly necessary while adding a few convenience styles from modern CSS specs.
| Description | Default | |
|---|---|---|
layer |
Optional CSS layer name to wrap the normalization rules. | undefined |
import { layer } from "@vanilla-extract/css"; import { normalize } from "bakeware"; const layoutLayer = layer("layout"); normalize(layoutLayer);
Adjusts the opacity of a color, with support for var declarations generated by createTheme.
| Description | Default | |
|---|---|---|
color |
The color string to modify. | — |
value |
A number between 0 and 1. |
— |
Makes implementing CSS transitions easy.
| Description | Default | |
|---|---|---|
properties |
CSS property names. | — |
options.behavior |
— | "normal" |
options.delay |
— | undefined |
options.duration |
— | "0s" |
options.timingFunction |
— | "ease" |
import { style } from "@vanilla-extract/css"; import { transition } from "bakeware"; const example = style({ transition: transition("opacity", "transform", { duration: 200, }).toString(), }); // .example { // transition: opacity 200ms,transform 200ms; // }
Adds declarations to the output using different options—see transition above for the available arguments.
import { transition } from "bakeware"; transition("opacity", { duration: "100ms" }) .add("height", { delay: 200, duration: "1s", timingFunction: "linear" }) .add("display", { behavior: "allow-discrete", duration: 500 }) .toString(); // "opacity 100ms,height 200ms linear 1s,display 500ms allow-discrete"
Returns the CSS transition string.
import { transition } from "bakeware"; transition("opacity").toString() // "opacity 0s"
Generates a transition function with its own default options—see transition above for the available options.
import { createTransition, transition } from "bakeware"; const customTransition = createTransition({ duration: 200 }); transition("opacity").toString(); // "opacity 0s" customTransition("opacity").toString(); // "opacity 200ms"
Makes implementing CSS animations easy.
| Description | Default | |
|---|---|---|
name |
Animation name. | — |
options.delay |
— | undefined |
options.direction |
— | "normal" |
options.duration |
— | "0s" |
options.fillMode |
— | undefined |
options.iterationCount |
— | "1" |
options.playState |
— | "running" |
options.timeline |
— | "auto" |
options.timingFunction |
— | "ease" |
import { keyframes } from "@vanilla-extract/css"; import { style } from "@vanilla-extract/css"; import { animation } from "bakeware"; const fade = keyframes({ from: { opacity: 0, }, to: { opacity: 1, }, }); const example = style({ animation: animation(fade, { duration: 200, }).toString(), }); // .example { // animation: 200ms fade; // }
Adds declarations to the output using different options—see animation above for the available arguments.
import { animation } from "bakeware"; animation("blur", { duration: "100ms" }) .add("slideOut", { delay: 200, duration: "1s", timingFunction: "linear" }) .add("blink", { duration: 500, playState: "paused" }) .toString(); // "100ms blur,200ms linear 1s slideOut,500ms paused blink"
Returns the CSS animation string.
import { animation } from "bakeware"; animation("blur").toString() // "0s blur"
Generates an animation function with its own default options—see animation above for the available options.
import { animation, createAnimation } from "bakeware"; const customAnimation = createAnimation({ duration: 200 }); animation("blur").toString(); // "0s blur" customAnimation("blur").toString(); // "200ms blur"
Extends vanilla-extract's fontFace, making the src definition cleaner. Fully compatible with the original function.
| Description | Default | |
|---|---|---|
rule |
— | — |
debugId |
— | — |
import { fontFace } from "bakeware"; fontFace({ src: { local: "Helvetica", opentype: { tech: "variations", url: "./helvetica.otf" }, truetype: "./helvetica.ttf", woff2: { url: "./helvetica.woff2" }, }, }); // local("Helvetica"),url("./helvetica.otf") format(opentype) tech("variations"),url("./helvetica.ttf") format(truetype),url("./helvetica.woff2") format(woff2) // Can also be used with an array of strings fontFace([ { src: [ 'local("Helvetica")', 'url("./helvetica.otf") format(opentype) tech("variations")', 'url("./helvetica.ttf") format(truetype)', 'url("./helvetica.woff2") format(woff2)', ], }, ]); // Can also be used like vanilla-extract original function fontFace([ { src: 'local("Helvetica"), url("./helvetica.otf") format(opentype) tech("variations"), url("./helvetica.ttf") format(truetype), url("./helvetica.woff2") format(woff2)', }, ]);
| Description | Default | |
|---|---|---|
value |
— | — |
Generates a set of media query strings for a given collection of breakpoints.
import { style } from "@vanilla-extract/css"; import { breakpoints } from "bakeware"; const breakpoint = breakpoints({ sm: "600px", md: "900px", lg: "1200px", }); // { // sm: "(min-width: 600px)", // md: "(min-width: 900px)", // lg: "(min-width: 1200px)", // not: { // sm: "not all and (min-width: 600px)", // md: "not all and (min-width: 900px)", // lg: "not all and (min-width: 1200px)", // }, // } style({ "@media": { // >= 900px [breakpoint.md]: { display: "flex", }, // < 900px [breakpoint.not.md]: { padding: "1rem", }, }, }); // @media (min-width: 900px) { // display: flex; // } // // @media not all and (min-width: 900px) { // padding: 1rem; // } // It accepts min, max and mediaType breakpoints({ mobile: { min: "240px", max: "479px" }, tablet: { min: "480px", max: "1023px" }, desktop: { min: "1024px" }, print: { mediaType: "print" }, }); // { // mobile: "(min-width: 240px) and (max-width: 479px)", // tablet: "(min-width: 480px) and (max-width: 1023px)", // desktop: "(min-width: 1024px)", // print: "print", // not: { // mobile: "not all and (min-width: 240px) and (max-width: 479px)", // tablet: "not all and (min-width: 480px) and (max-width: 1023px)", // desktop: "not all and (min-width: 1024px)", // print: "not print" // } // }
Extends vanilla-extract's createTheme, exposing the vars values. Fully compatible with the original implementation.
| Description | Default | |
|---|---|---|
themeContract |
— | — |
tokens |
— | — |
debugId |
— | — |
Used to access the value of a custom property generated by createTheme.
| Description | Default | |
|---|---|---|
declaration |
The value returned by createTheme. |
— |
import { createTheme } from "bakeware"; const [_, vars] = createTheme({ example: "#000", }); // { // example: "var(--example_xxxxxxx)", // } createTheme.var(vars.example); // "#000"
Sets global styles for multiple selectors. The rules object accepts the same selector-based global styles as vanilla-extract, with optional top-level named layers.
| Description | Default | |
|---|---|---|
rules |
Object containing selectors and optional named layers. | — |
import { globalStyles } from "bakeware"; globalStyles({ "*": { boxSizing: "border-box", }, svg: { display: "inline-block", }, });
Top-level @layer groups selectors under named CSS layers:
globalStyles({ "@layer": { reset: { "*": { boxSizing: "border-box", }, html: { blockSize: "100%", }, }, components: { button: { cursor: "pointer", }, }, }, }); // @layer reset { // * { box-sizing: border-box; } // html { block-size: 100%; } // } // // @layer components { // button { cursor: pointer; } // }
Selector-level @layer rules continue to use vanilla-extract's existing syntax:
globalStyles({ body: { "@layer": { base: { margin: 0, }, }, }, });
Copyright (C) 2026-present stldo