kevintngo/looseleaf
Developer ToolsA hand-drawn React component library with 123 accessible shadcn/ui-compatible parts, blocks, icons and art, distributed through a shadcn registry.
What it is
Looseleaf is a React component library built on Tailwind v4 and Radix, with every surface styled as paper and every line drawn like pen ink. It keeps shadcn/ui's parts, props and data-slot names, so existing JSX can generally swap in Looseleaf components without structural changes. The decoration is visual; the underlying semantics remain standard Radix.
The package covers 123 components, 61 blocks (sidebars, logins, dashboards, chat, pricing and more), 160 icons, 48 doodles, 88 stickers, badges and stamps, plus a hand-drawn typeface called Kevin Sans. Accessibility claims include keyboard operation, visible focus, AA text, 24 px targets, reduced motion, forced colors, RTL support and three densities.
Install and use
Add the registry to components.json once:
{
"registries": { "@looseleaf": "https://kevintngo.github.io/looseleaf/r/{name}.json" }
}
Then pull in individual items with the shadcn CLI:
npx shadcn@latest add @looseleaf/button
npx shadcn@latest add @looseleaf/login-01
npx shadcn@latest add @looseleaf/looseleaf
Components arrive as source files in components/ui/*.tsx and lib/ink/*, so they become part of your codebase rather than a runtime dependency. The umbrella looseleaf item appears to bring in the theme, including Kevin Sans; to load the font manually instead, import the published CSS:
@import url("https://kevintngo.github.io/looseleaf/fonts/kevin-sans.css");
Wrap the app in InkProvider and use the generated components normally:
import { InkProvider } from "@/lib/ink/react"
import { Button } from "@/components/ui/button"
export function App() {
return (
<InkProvider>
<Button>Save changes</Button>
</InkProvider>
)
}
The live documentation site is at kevintngo.github.io/looseleaf, and the shadcn registry format is documented at ui.shadcn.com.
How the drawing works
Each drawn element is a single <svg data-ink> placed behind the real DOM label. The drawing comes from a pure, seeded TypeScript function in src/lib/ink/recipes/<component>-ink.ts that writes SVG colored by CSS variables, so the same seed produces the same line on server and client. Hover, press and focus states are handled in CSS by revealing layers that were drawn ahead of time, rather than by React state. Colors, pen widths and densities are exposed as --ll-* tokens aliased to shadcn semantic variables, which is the main customization surface.
Constraints
- Built for React with Tailwind v4 and the shadcn CLI; the install flow assumes an existing shadcn-style setup with a
components.json. - Components are copied into your repository as source, so you own and maintain the generated files.
- Code, art and Kevin Sans are MIT-licensed; IBM Plex Mono is SIL OFL 1.1.
Development
For local work on the library or docs site:
npm install
npm run dev # documentation site
npm run build # static site in dist/
npm test # vitest
npm run registry:build # registry.json and public/r/*.json
Run npm run registry:build after changing a component so the registry serves the updated source. Pushing to main deploys the site to GitHub Pages.
HotRepo's take
Looseleaf entered HotRepo's new-project board for the TypeScript language on 2026-11-03, recording 107 stars and 5 new stars in the measured window. Its recorded star count moved from 102 to 107 between the 2026-11-02 and 2026-11-03 UTC observations. That is a short series and a small sample, so it shows early attention rather than an established trajectory. The practical differentiator is the shadcn-registry distribution: because the output is ordinary component source with Radix semantics, teams can evaluate readability and accessibility on the live site before committing to the visual style.
Written by AI from the project's README, updated . The project's own docs are the source of truth.