CSS Hooks
Documentation
Source on GitHub

Quickstart: No framework

1 Create the project

npm create vite@latest css-hooks-playground -- --template vanilla-ts cd css-hooks-playground npm install @css-hooks/core@next remeda

2 Define a hook

Create a module for styling utilities:

src/css.ts
import { createHooksSystem } from "@css-hooks/core"; const { createHooks } = createHooksSystem(); export const { on, styleSheet } = createHooks("&:active");

3 Render the generated stylesheet

Add the generated stylesheet to the document once near the application entry point:

src/main.ts
import { styleSheet } from "./css"; const style = document.createElement("style"); style.textContent = styleSheet(); document.head.append(style);

4 Apply an override style

The core package returns a style object, so convert it to an inline style string before applying it. This minimal example only supports the string values used below; use a renderer-appropriate serializer in an application.

src/main.ts
import { pipe } from "remeda"; import { on } from "./css"; function styleObjectToString(style: Record<string, string>) { return Object.entries(style) .map(([property, value]) => `${property}: ${value}`) .join("; "); } const buttonStyle = pipe( { transition: "transform 75ms" }, on("&:active", { transform: "scale(0.9)" }), ); document .querySelector<HTMLButtonElement>("#button")! .setAttribute("style", styleObjectToString(buttonStyle));

Run npm run dev to try it. Continue to Configuration to define more hooks, then see Usage for composition patterns.