A motion-first, physics-based React component library.
40 composable primitives that turn animation from a feature into a language.
Quick Start · Primitives · Physics · Accessibility · Architecture
Every UI library treats animation as decoration — a per-component config you tweak until it "feels right." FLUX UI takes a different stance: motion is a grammar. A button's hover, a modal's entrance, a page transition, and a skeleton loader's pulse should all speak the same visual language.
FLUX UI provides that language through 40 motion primitives, a unified physics engine, and a composable architecture where wrapping <Magnetic> around <Reveal> around a <button> just works.
What makes it different:
- Physics-first defaults — 7 named spring presets (
snappy,smooth,gentle,dramatic,bouncy,cinematic,instant) replace magic number configs. Every animation is driven by real stiffness, damping, and mass values. - Composable, not configurable — Small primitives that combine like Unix pipes for motion, instead of mega-components with 50 props each.
- AI-native patterns — First-class primitives for streaming text, typing indicators, skeleton loaders, and AI chat interfaces.
- Accessibility built in — Three-tier system: OS
prefers-reduced-motion→ FluxProvidermotionLevel→ per-primitivedisabledprop. Reduced motion never disables — it gracefully degrades to opacity crossfades. - Zero visual lock-in — Primitives add motion behavior only. All visual styling lives in your Tailwind classes.
npm install @nikitph/flux-uiPeer dependencies: react >= 19, react-dom >= 19, motion >= 12, tailwindcss >= 4
import { FluxProvider } from "@nikitph/flux-ui";
function App() {
return (
<FluxProvider motionLevel="full">
{/* your app */}
</FluxProvider>
);
}import { Reveal, Magnetic, HoverScale } from "@nikitph/flux-ui";
function Hero() {
return (
<Reveal from="below">
<h1>Welcome</h1>
<p>Motion is not a feature. It is a language.</p>
<Magnetic strength={0.3}>
<HoverScale hoverScale={1.05}>
<button className="px-6 py-3 bg-teal-500 text-white rounded-xl">
Get Started
</button>
</HoverScale>
</Magnetic>
</Reveal>
);
}Primitives compose freely — nest them, combine them, and let the physics engine handle the rest.
40 motion primitives across 6 categories.
| # | Primitive | Description |
|---|---|---|
| 01 | Reveal |
Fade + directional slide on viewport entry |
| 02 | Presence |
Mount/unmount with enter/exit animations |
| 03 | Stagger |
Sequentially animate child elements |
| 04 | TextReveal |
Character or word-level text entrance |
| 05 | CountUp |
Animated number counter |
| 06 | MorphText |
Smooth text content transitions |
| 07 | FlipCard |
3D card flip with front/back faces |
| 08 | Collapse |
Smooth height expand/collapse |
| # | Primitive | Description |
|---|---|---|
| 09 | Magnetic |
Cursor-attracted element displacement |
| 10 | HoverScale |
Scale transform on hover |
| 11 | Tilt |
Perspective tilt following pointer position |
| 12 | Drag |
Physics-based drag with constraints |
| 13 | Swipe |
Swipe-to-dismiss / swipe-to-action |
| 14 | LongPress |
Press-and-hold interaction with progress |
| 15 | Hover3D |
Multi-layer parallax depth on hover |
| 16 | ScrollVelocity |
Speed-reactive scroll animations |
| 17 | Spotlight |
Radial gradient follows cursor |
| 18 | FollowCursor |
Element tracks cursor position |
| # | Primitive | Description |
|---|---|---|
| 19 | Morph |
Shared-layout morphing transitions |
| 20 | FluidLayout |
Animated layout reflow |
| 21 | Reorder |
Drag-to-reorder with animated layout |
| 22 | PageTransition |
Route-level enter/exit transitions |
| 23 | AnimatedList |
Auto-animate list item add/remove |
| 24 | Marquee |
Infinite horizontal/vertical scroll |
| 25 | Dock |
macOS-style magnifying dock |
| 26 | InfiniteScroll |
Virtualized infinite scroll with motion |
| # | Primitive | Description |
|---|---|---|
| 27 | ScrollProgress |
Scroll-linked progress indicator |
| 28 | Parallax |
Depth-based scroll parallax layers |
| 29 | StickyScroll |
Scroll-driven sticky reveal sections |
| 30 | ScrollSnap |
Physics-based snap scrolling |
| # | Primitive | Description |
|---|---|---|
| 31 | Aurora |
Animated aurora borealis gradient |
| 32 | MeshGradient |
Morphing mesh gradient background |
| 33 | Particles |
Configurable particle field |
| 34 | GridPattern |
Animated dot/line grid |
| 35 | Noise |
Animated grain/noise texture overlay |
| # | Primitive | Description |
|---|---|---|
| 36 | StreamingText |
Token-by-token text reveal |
| 37 | TypingIndicator |
Animated typing dots |
| 38 | Skeleton |
Content placeholder with shimmer |
| 39 | AIMessage |
Chat bubble with streaming support |
| 40 | HeroHighlight |
Animated text emphasis highlight |
Every spring animation is driven by named physics presets — no magic numbers.
| Preset | Stiffness | Damping | Mass | Best for |
|---|---|---|---|---|
snappy |
500 | 30 | 0.5 | Buttons, toggles, micro-interactions |
smooth |
200 | 20 | 1.0 | General transitions, reveals |
gentle |
120 | 14 | 1.0 | Background shifts, ambient motion |
dramatic |
80 | 10 | 1.5 | Hero entrances, page transitions |
bouncy |
400 | 15 | 1.0 | Playful interactions, attention |
cinematic |
50 | 12 | 2.0 | Full-screen reveals, slow drama |
instant |
800 | 40 | 0.3 | Immediate feedback, no perceptible delay |
Override per-primitive:
<Reveal physics="dramatic" from="below">
<h1>Grand Entrance</h1>
</Reveal>Or configure globally:
<FluxProvider physics="smooth">
{/* all children default to smooth springs */}
</FluxProvider>FLUX UI implements a three-tier accessibility strategy:
Tier 1 — OS Level. Automatically detects prefers-reduced-motion via usePrefersReducedMotion(). When active, all spatial animations (translate, scale, rotate) are replaced with 150ms opacity crossfades. Nothing is disabled — every primitive still communicates state changes.
Tier 2 — Provider Level. The FluxProvider accepts a motionLevel prop ("full", "reduced", "none") for app-wide control, independent of OS settings.
Tier 3 — Primitive Level. Every primitive accepts a disabled prop to opt out of motion on a case-by-case basis.
// OS-level detection is automatic
// Provider-level override:
<FluxProvider motionLevel="reduced">
{/* All primitives use reduced motion */}
<Reveal disabled>{/* This specific one has no motion */}</Reveal>
</FluxProvider>FLUX UI is built on a five-layer architecture:
┌─────────────────────────────────┐
│ Layer 5 — Scenes │ Full page compositions
├─────────────────────────────────┤
│ Layer 4 — Patterns │ Multi-primitive recipes
├─────────────────────────────────┤
│ Layer 3 — Components │ Single-purpose UI elements
├─────────────────────────────────┤
│ Layer 2 — Primitives (×40) │ Motion behaviors
├─────────────────────────────────┤
│ Layer 1 — Motion Tokens │ Physics presets, scales, config
└─────────────────────────────────┘
Primitives live at Layer 2. They add motion behavior only — never visual styling. You bring your own design system, your own Tailwind classes, your own component library. FLUX UI handles the motion.
- Radix Slot pattern — Every primitive supports
asChildfor zero-wrapper composition. - Ref forwarding — All 40 primitives forward refs via
React.forwardRef. - SSR safe — No
windowordocumentaccess at render time. All browser APIs live inside effects. - Tree-shakeable — Import only what you use. Each primitive is independently importable.
- < 3KB per primitive — Every primitive targets under 3KB gzipped (excluding the
motionpeer dependency).
8 utility hooks available for custom motion work:
| Hook | Description |
|---|---|
usePhysics(preset) |
Returns spring config for a named preset |
usePrefersReducedMotion() |
Raw prefers-reduced-motion media query |
useReducedMotion() |
Computed boolean factoring provider + OS |
useIsClient() |
SSR guard — false on server, true on client |
useMergedRef(...refs) |
Merge forwarded ref + internal ref |
useInView(options) |
IntersectionObserver wrapper |
useScrollProgress(ref) |
Element scroll position as 0→1 |
useAnimationBudget() |
Register/deregister active animations |
| Layer | Technology |
|---|---|
| Framework | React 19 |
| Animation | Motion (Framer Motion) |
| Styling | Tailwind CSS v4 |
| Composition | Radix UI Slot |
| Language | TypeScript 5.9 (strict) |
| Build | Vite 7 |
# Install dependencies
npm install
# Start dev server
npm run dev
# Type check
npx tsc -b
# Build for production
npm run build
# Preview production build
npm run previewMIT © nikitph
Motion is not a feature. It is a language.