website with
Eunary
modern
Beautiful, accessible, and highly customizable React components that help you build modern interfaces with extraordinary speed.
Ready-to-use Components
Simply copy the code into your ui folder and start importing components right away — no extra setup


Copy the component
Select and copy the component code.
Drop into your UI folder
Paste it into your components directory.
Start using immediately
Import and use in your projects.
Even simpler with CLI
Install components directly from your terminal with a single command
One-Click Copy
Copy any component with a single click and paste it directly into your project.
Zero Setup
No complex installation or configuration. Just drop and go.
Ready to Use
Every component is production-ready with proper styling and functionality.
UI Components
Discover a collection of beautifully crafted, interactive UI components built with React, Framer Motion, and modern design principles.
Scrolling MacBook
Interactive 3D MacBook with scroll-triggered animations and hover effects.
Flip Words
Animated text that cycles through words with smooth transitions in a sentence.
Amazing
File Upload
Drag & drop file upload with animations.
Upload file
Click or just drag & drop your files here
iOS Notifications
Stack of notifications with iOS-style animations.
Click to expand
Your favorite artist just released a new track. Listen now!
You’ve completed your tasks 5 days in a row. Keep it going!
A post you liked is going viral! See what people are saying.
Fully Customizable Components
Tailor every component to match your brand’s style with ease—change colors, sizes, and behavior without touching the core functionality.
Customize Your Component
'use client'; import { useEffect, useRef } from 'react'; import createGlobe from 'cobe'; import { useSpring } from 'react-spring'; import { Sparkles } from './sparkles'; import { motion, useScroll, useTransform, useMotionTemplate, } from 'motion/react'; import { cn } from '@/lib/utils'; interface props { globeClassName?: string; containerClassName?: string; textClassName?: string; text?: string; textSize?: 'xl' | 'lg' | 'md' | 'sm'; globeSize?: number; globeRotateDirection?: 'left' | 'right'; } export const FeaturedGlobe = ({ globeClassName, containerClassName, textClassName, text = 'EUNARY UI', textSize = 'md', globeSize = 500, globeRotateDirection = 'right', }: props) => { const containerRef = useRef<HTMLDivElement>(null); const { scrollYProgress } = useScroll({ target: containerRef, offset: ['start end', 'end center'], }); const textY = useTransform( scrollYProgress, [0, 0.25, 0.5, 0.75], [300, 100, 0, -100] ); const textOpacity = useTransform( scrollYProgress, [0, 0.25, 0.5, 0.75], [0, 0, 0.5, 1] ); const textScale = useTransform( scrollYProgress, [0, 0.25, 0.5, 0.75], [0.8, 0.85, 0.9, 1] ); const textBlur = useTransform( scrollYProgress, [0, 0.2, 0.4, 0.6], [9, 6, 3, 0] ); const getTextSizeClasses = () => { switch (textSize) { case 'sm': return 'text-4xl sm:text-5xl md:text-6xl lg:text-7xl'; case 'md': return 'text-5xl sm:text-6xl md:text-7xl lg:text-8xl'; case 'lg': return 'text-6xl sm:text-7xl md:text-8xl lg:text-9xl'; case 'xl': default: return 'text-6xl sm:text-7xl md:text-8xl lg:text-9xl xl:text-[10rem]'; } }; const textSizeClasses = getTextSizeClasses(); return ( <div className="relative h-full w-full"> <div ref={containerRef} className={cn( 'sticky flex min-h-[30rem] w-full items-center justify-center overflow-hidden', containerClassName )} > {/* Globe Component */} <div className="absolute -bottom-48 z-20 flex aspect-[1] items-center justify-center"> <Globe globeSize={globeSize} globeClassName={globeClassName} globeRotateDirection={globeRotateDirection} /> </div> {/* Animated Text */} <motion.div style={{ y: textY, opacity: textOpacity, scale: textScale, filter: useMotionTemplate`blur(${textBlur}px)`, }} className="absolute z-10 flex items-center justify-center text-nowrap" > <div className={cn( 'bg-gradient-to-b from-white to-gray-600 bg-clip-text text-center font-bold text-transparent', textSizeClasses, textClassName )} > {text} </div> </motion.div> {/* Background Sparkles */} <Sparkles background="transparent" minSize={0.4} maxSize={1} particleDensity={50} className="z-0 h-full w-full" particleColor="#ffffff" speed={2} /> </div> </div> ); }; const Globe = ({ globeClassName, globeSize, globeRotateDirection, }: { globeClassName?: string; globeSize: number; globeRotateDirection?: 'left' | 'right'; }) => { const canvasRef = useRef<HTMLCanvasElement>(null); const pointerInteracting = useRef<number | null>(null); const pointerInteractionMovement = useRef(0); const [{ r }, api] = useSpring(() => ({ r: 0, config: { mass: 1, tension: 280, friction: 40, precision: 0.001, }, })); useEffect(() => { let phi = 0; const width: number = globeSize; if (!canvasRef.current) return; const globe = createGlobe(canvasRef.current, { devicePixelRatio: 2, width: width * 2, height: width * 2, phi: 0, theta: 0.3, dark: 1, diffuse: 3, mapSamples: 16000, mapBrightness: 1.2, baseColor: [1, 1, 1], markerColor: [40 / 255, 100 / 255, 215 / 255], glowColor: [255 / 255, 255 / 255, 255 / 255], markers: [ { location: [28.61402, 77.22955], // Delhi size: 0.1, }, { location: [40.75833, -73.99167], // New York size: 0.2, }, { location: [22.575, 88.325], // Kolkata size: 0.05, }, { location: [25.18333, 55.26667], // Dubai size: 0.05, }, ], onRender: (state) => { // This prevents rotation while dragging if (!pointerInteracting.current) { // Called on every animation frame. // `state` will be an empty object, return updated params. globeRotateDirection === 'left' ? (phi -= 0.005) : (phi += 0.005); } state.phi = phi + r.get(); state.width = width * 2; state.height = width * 2; }, }); setTimeout( () => canvasRef.current && (canvasRef.current.style.opacity = '1') ); return () => { globe.destroy(); }; }, []); return ( <div className={cn('rounded-full', globeClassName)} style={{ width: 500, height: 500, maxWidth: 600, aspectRatio: 1, margin: 'auto', position: 'relative', }} > <canvas ref={canvasRef} onPointerDown={(e) => { pointerInteracting.current = e.clientX - pointerInteractionMovement.current; canvasRef.current && (canvasRef.current.style.cursor = 'grabbing'); }} onPointerUp={() => { pointerInteracting.current = null; canvasRef.current && (canvasRef.current.style.cursor = 'grab'); }} onPointerOut={() => { pointerInteracting.current = null; canvasRef.current && (canvasRef.current.style.cursor = 'grab'); }} onMouseMove={(e) => { if (pointerInteracting.current !== null) { const delta = e.clientX - pointerInteracting.current; pointerInteractionMovement.current = delta; api.start({ r: delta / 200, }); } }} onTouchMove={(e) => { if (pointerInteracting.current !== null && e.touches[0]) { const delta = e.touches[0].clientX - pointerInteracting.current; pointerInteractionMovement.current = delta; api.start({ r: delta / 100, }); } }} style={{ width: '100%', height: '100%', cursor: 'grab', contain: 'layout paint size', opacity: 0, transition: 'opacity 1s ease', }} /> </div> ); };
Why developers love Eunary UI
Built for modern web development with performance, accessibility, and developer experience at its core.
Lightning Fast
Optimized animations that run at 60fps with minimal performance impact on your applications.
Fully Customizable
Every component is built with customization in mind. Change colors, timing, and behavior easily.
Developer Friendly
Pre build components with intuitive usage, strong TypeScript support, and easy integration.
Accessibility First
Built with accessibility in mind, supporting screen readers and respecting user preferences.
Mobile Optimized
Touch-friendly interactions and responsive animations that work perfectly on all devices.
Dark Mode Ready
Built-in dark mode support with seamless theme transitions and proper contrast ratios.

