Tactile, dark-first React component library built on Radix primitives.
Old-iOS skeuomorphism × macOS Sequoia neatness × Ubuntu warmth.
Install
Add the registry to your project .npmrc:
@olly:registry=https://git.ollyhearn.ru/api/packages/olly/npm/
Then install:
npm install @olly/@olly/modern-sk
react and react-dom (>=18) are peer dependencies — your app provides them.
Usage
Import the stylesheet once at your app root, then use components anywhere:
import '@olly/modern-sk/styles.css'; // required — tokens + components
import '@olly/modern-sk/fonts.css'; // optional — branded faces (see Fonts)
import { ThemeProvider, TooltipProvider, Button, Card } from '@olly/modern-sk';
export function App() {
return (
<ThemeProvider>
<TooltipProvider delayDuration={200}>
<Card>
<Button variant="primary">Click</Button>
</Card>
</TooltipProvider>
</ThemeProvider>
);
}
ThemeProvidermanages dark/light viadata-themeon<html>and persists tolocalStorage. Read it withuseTheme().TooltipProvidermust wrap any tree that uses<Tooltip>.- All visuals come from CSS custom properties in the shipped stylesheet.
Fonts
@olly/modern-sk/styles.css ships no fonts. The type tokens default to a chain
that degrades to system-ui, so the library works with zero font loading.
To get the branded ModernSK faces (Anta display + Onest + Geist Mono), import the optional stylesheet — Anta is self-hosted and inlined, no asset hosting needed:
import '@olly/modern-sk/fonts.css';
To use your own fonts, skip fonts.css and override the tokens anywhere
after styles.css — every component re-reads them:
:root {
--font-display: 'Your Display', sans-serif;
--font-sans: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
}
Develop
npm run dev # Rsbuild playground (every component on one page) at http://localhost:3000
npm run storybook # Storybook component explorer + docs at http://localhost:6006
npm run build # build the publishable package into dist/
npm run lint
Storybook is the component catalogue: each component has live controls and an
auto-generated prop table, plus a theme toggle in the toolbar. Stories live in
src/stories/*.stories.tsx; config is in .storybook/. It is committed to git so
anyone can npm run storybook and browse — but it never ships in the package.
What ships
A git install exposes only dist/ — built ESM + CJS, .d.ts types,
styles.css, and fonts.css. Everything else (src/App.tsx, .storybook/,
stories, Rsbuild config) is dev-only and never published.
brought to you by ollyhearn & claude with <3