- Utility functions for vanilla-extract
- TypeScript-ready, with built-in type definitions
- Simplifies working with @layer
- 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 bakewareExtends vanilla-extract's style, enabling a cleaner way to implement layers. If layer is not set, it behaves like the original function.
| Description | Default | |
|---|---|---|
layer |
CSS @layer name. |
undefined |
rule |
— | — |
debugId |
— | undefined |
import { style } from "bakeware";
// With layer
const withLayer = style("base", {
color: "blue",
});
// @layer base {
// .withLayer {
// color: blue;
// }
// }
// Without layer
const withoutLayer = style({
color: "red",
});
// .withoutLayer {
// color: red;
// }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, 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 { animation, style } 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 { breakpoints, style } 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"Extends vanilla-extract's globalStyle, enabling a cleaner way to implement layers. If layer is not set, it behaves like the original function.
| Description | Default | |
|---|---|---|
layer |
CSS @layer name. |
undefined |
selector |
— | — |
rule |
— | — |
import { globalStyle } from "bakeware";
globalStyle("reset", "*", {
boxSizing: "border-box",
});
// @layer reset;
//
// @layer reset {
// * {
// box-sizing: border-box;
// }
// }Sets global styles all at once, with layer support.
| Description | Default | |
|---|---|---|
layer |
CSS @layer name. |
undefined |
rules |
Object containing selectors as keys and rules as values. | — |
import { globalStyles } from "bakeware";
globalStyles("reset", {
"*": {
boxSizing: "border-box",
},
svg: {
display: "inline-block",
},
});
// @layer reset;
//
// @layer reset {
// * {
// box-sizing: border-box;
// }
// svg {
// display: inline-block;
// }
// }Copyright (C) 2026-present stldo