CSSCSS Houdini Overview

CSS Houdini Overview

CSS Houdini is not a single feature but a collection of low-level APIs that expose parts of the browser's CSS rendering engine directly to JavaScript. Historically, if CSS couldn't do something — a custom paint effect, a custom layout algorithm — the only option was to abandon CSS for that part and reimplement the whole visual behavior in JavaScript, usually by measuring elements and pushing around absolutely-positioned divs. Houdini's philosophy is narrower and more surgical: if you can't do it in CSS, write a small, focused worklet that plugs into the specific stage of the rendering pipeline you need, and let the browser continue handling everything else — layout, compositing, painting — exactly as it normally would.

The Houdini family of APIs

API

What it exposes

Status

Properties and Values API

Registering typed, animatable custom properties — this is what @property is actually built on (see @property — typed custom properties)

Broadly available — the Houdini API most developers actually touch

Paint API

A paint() worklet that draws custom backgrounds/borders with Canvas-like drawing commands — see CSS Paint API

Available in Chromium-based browsers; check other engines

Typed OM (Typed Object Model)

Reading/writing CSS values as structured typed objects from JS instead of parsing strings — see CSS Typed Object Model

Partial — core pieces are available, the full spec is still evolving

Layout API

A layout() worklet that defines a fully custom layout algorithm, usable via display: layout(myLayoutName)

Experimental / limited — not broadly shipped

Animation Worklet

High-performance, off-main-thread scroll- and gesture-driven animations

Mostly superseded in practice by native scroll-driven animations and the View Transitions API

Why @property matters more day-to-day
Of everything on that list, the Properties and Values API is the one most developers will actually run into, because it's exposed through plain CSS syntax rather than requiring you to write and register a JavaScript worklet module. Declaring @property --my-value { ... } is Houdini — you're registering a property with the same underlying mechanism a worklet-based feature would use — but it reads and feels like ordinary CSS.

CSS
/* This is CSS syntax, but it's Houdini under the hood — it
   registers a typed custom property via the Properties and
   Values API, without ever touching JavaScript. */
@property --highlight-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
The worklet pattern, in general

The other Houdini APIs follow a shared shape: register a small JavaScript class in a worklet module, then reference it by name from CSS. The Paint API page walks through this in detail with a concrete example.

JS
// A minimal illustration of the general worklet shape —
// register a class with a defined "hook" method, then use
// it from CSS by the name it was registered under.
CSS.paintWorklet.addModule('my-worklet.js')

// inside my-worklet.js:
class MyPainter {
  paint(ctx, size, properties) {
    // draw using Canvas-like APIs
  }
}
registerPaint('my-painter', MyPainter)
Note
Houdini adoption has been considerably slower and more niche than the original vision suggested when it was first announced. Several of its APIs remain experimental or Chromium-only years after introduction, and most teams never write a worklet at all. In everyday work, you're far more likely to reach for @property than to write a Paint API worklet or a Layout API worklet — but knowing the family exists explains where @property actually comes from, and gives you a mental map for what to search for if you ever hit a wall that plain CSS genuinely can't clear.
Next
See a concrete worklet in action: [CSS Paint API](/css/paint-api).