Repo of the Day
lucasmarkes/hairline: Six isometric line figures that answer the pointer. For React and for anything with a DOM.
Published: Oct 16, 2026
Open repository ↗Six isometric line figures that answer the pointer. For React and for anything with a DOM. - lucasmarkes/hairline
Summary
@lucasmarkes/hairline is a TypeScript library that renders pointer-driven isometric SVG line figures. It works in React and in any DOM environment, ships with no runtime dependencies, and is themed through CSS custom properties.
What it is useful for
Adding small, interactive decorative elements to landing pages, hero sections, empty states, or documentation headers. The README catalogs 33 named figures — including Terrain (pillars that rise around the cursor), Turntable (blocks on a rotating disc that settles on a quarter turn), Phosphor (a dot matrix the cursor paints), Vault (a dial whose combination draws the bolts back), and Stack (a call stack whose frames lift apart) — each reacting to pointer position with adjustable intensity. For shadcn/ui users the package integrates with the theme tokens, and Phosphor and Slow honor prefers-reduced-motion by holding still.
How engineers can use it
Install with npm i @lucasmarkes/hairline. The package is ESM-only, with React 18+ as an optional peer needed only by the /react entry.
In a React app:
import { Terrain } from "@lucasmarkes/hairline/react";
export function Hero() {
return <Terrain />;
}
In any DOM environment (the README gives a Svelte action example):
import { terrain } from "@lucasmarkes/hairline";
const figure = terrain(document.getElementById("figure")!, { play: true });
figure.update({ intensity: 0.8 });
figure.destroy();
Each figure fills its parent at a 5:4 aspect ratio. All five options — intensity (default 0.5), theme ("auto" | "light" | "dark"), label, onRead, and play — are documented in the README; update mutates a live figure, destroy removes it. One requestAnimationFrame loop drives every figure on the page, idle figures do no work, and a Server Component renders an empty 5:4 box so nothing shifts when the client draws.
For shadcn/ui: npx shadcn@latest add https://hairline.lucasmarkes.com/r/hairline.json. To build a new figure from an idea, install the hairline-create agent skill with npx skills add lucasmarkes/hairline and run /hairline-create ....
Documented limitations: the DOM-based functions need a real DOM (call them in an effect, in onMount, or after the element mounts); only Riffle is keyboard-focusable; --hairline-plate is an opaque fill, so on backgrounds other than white or #08090a it must be set to match; and on the server the component renders nothing until client-side hydration.