MicroKit
A component library for developers who care about the experience behind every interaction. 30 ready-to-use microinteractions, each available as React or plain CSS, tagged by what triggers them.
- Role
- Author
- Year
- 2026
- Stack
- React, TypeScript, Tailwind CSS, Next.js
Why it exists
Most component libraries solve layout and skip feel. You get a button that is the right size, the right colour and the right shape, and does nothing interesting when you touch it.
The gap between those two buttons is small, cheap, and almost entirely what separates software that feels considered from software that feels assembled.
MicroKit is thirty of those small things, ready to paste.
What is in it
Interactions are organised by what triggers them — hover, click, focus — rather than by what they are attached to, because the trigger is the part you are actually designing around.
- Buttons — magnetic fill, gradient underline, glow, neon invert
- Inputs — focus field
- Navigation — spotlight indicator, sliding tabs
- Text — swap, reveal
Each one ships as React and as plain CSS, so it drops into a Next.js app or a static page with equal effort.
Decisions I would defend
Copy-paste over install. A dependency you cannot edit is a dependency you will fight. These are small enough to own outright, so you own them.
Framework-plural. The React version is the convenient one; the CSS version is the one that proves the interaction does not need a runtime.
Trigger-first taxonomy. Sorting by "button / input / nav" tells you where a thing goes. Sorting by hover / click / focus tells you what it does, which is the question you actually have.
Status
Open source, MIT, on GitHub. Live at microkit.co.
export function MagneticFill({ children }) {
const x = useMotionValue(50);
const y = useMotionValue(50);
// The fill grows from wherever the
// cursor entered — never the centre.
const bg = useMotionTemplate`
radial-gradient(circle at ${x}% ${y}%,
var(--fill) 0%, transparent 70%)
`;
return (
<motion.button
style={{ background: bg }}
onPointerMove={track(x, y)}
>
{children}
</motion.button>
);
}