Hyper-realistic eyes that follow your cursor with smooth spring physics, reactive pupil dilation, natural blinking, and multiple stunning variants. Move your mouse around to see the magic.
pnpm dlx shadcn@latest add @componentry/eye-trackingDependencies: framer-motion clsx tailwind-merge
| Prop | Type | Default |
|---|---|---|
eyeSize | numberSize of each eye in pixels. | 120 |
gap | numberGap between eyes in pixels. | 40 |
variant | "realistic" | "cartoon" | "minimal" | "cyber"Visual style variant. | "realistic" |
irisColor | stringPrimary iris color. | "#4A6741" |
irisColorSecondary | stringSecondary iris color for gradient. | "#6B8F62" |
pupilColor | stringColor of the pupil. | "#0a0a0a" |
scleraColor | stringColor of the sclera (white of the eye). | "#F5F0EB" |
pupilRange | numberHow far the pupil can travel (0-1). | 0.7 |
eyeCount | numberNumber of eyes to render. | 2 |
showReflection | booleanShow light reflection glint on the eye. | true |
showIrisDetail | booleanShow iris fiber/pattern details. | true |
reactivePupil | booleanPupil dilates based on cursor proximity. | true |
showEyelids | booleanShow eyelid shadow gradients. | true |
blinkInterval | numberBlink interval in ms. Set to 0 to disable. | 4000 |
idleAnimation | booleanSubtle random movement when cursor is idle. | true |
className | stringAdditional CSS classes. | — |
Use the eyes as a playful detail in a hero, empty state, or illustration. Keep instructions and important feedback in text rather than relying on eye movement.
eyeSize and gap set the proportions, while pupilRange limits how far pupils can move. Try the realistic, cartoon, minimal, and cyber variants against the surrounding interface.
blinkInterval is measured in milliseconds; set it to 0 to disable periodic blinking. Check pointer and touch behavior separately, and provide your own motion policy if the surrounding product requires one.
Keep in mind
Need a custom component?
I build bespoke UI components & websites tailored to your brand.
import { EyeTracking } from "@/components/ui/eye-tracking"
<EyeTracking eyeSize={140} gap={50} />