A lightweight, TypeScript-first React library for creating beautiful custom cursors with SSR support, smooth animations, and zero dependencies. Perfect for interactive websites, games, and creative applications.
npm install @yhattav/react-component-cursor






A flexible and customizable React component for creating smooth, interactive custom cursors and enhancements.
- Use any React component
- Smooth cursor movement with configurable smoothing
- Global and Container-specific cursors
- Supports Multiple instances
- Lightweight (<10KB)
- Zero dependencies (except React)
``bash`
npm install @yhattav/react-component-cursor
or
yarn add @yhattav/react-component-cursor
Note: If you wish to, You'll need to hide the native cursor with CSS (like cursor: none in the example above). See our styling guide for different approaches.
š New to the library? Check out our comprehensive Getting Started Guide for step-by-step tutorials and examples.
`tsx
import { CustomCursor } from '@yhattav/react-component-cursor';
function App() {
return (
<>
{/ Hide native cursor globally /}
style={{
width: '20px',
height: '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
}}
/>
{/ Your app content /}
>
);
}
`
The main component for creating custom cursors.
#### Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | ReactNode | - | The React component/element to use as cursor content |enabled
| | boolean | true | Whether the cursor is enabled and visible |smoothness
| | number | 1 | Movement smoothing factor (1=instant, higher=smoother) |containerRef
| | RefObject | - | Limit cursor to specific container element |offset
| | CursorOffset | { x: 0, y: 0 } | Pixel offset from mouse position |centered
| | boolean | true | Auto-center cursor content on mouse position |throttleMs
| | number | 0 | Throttle mouse events in milliseconds |className
| | string | '' | Additional CSS classes for cursor container |style
| | CSSProperties | {} | Additional inline styles for cursor container |zIndex
| | number | 9999 | CSS z-index for cursor container |onMove
| | CursorMoveHandler | - | Callback fired on cursor movement |onVisibilityChange
| | CursorVisibilityHandler | - | Callback fired when cursor visibility changes |id
| | string | auto-generated | Unique identifier for cursor instance |showDevIndicator
| | boolean | true | [Dev Only] Show debug ring in development |data-testid
| | string | - | Test ID for automated testing |role
| | string | - | ARIA role for accessibility |aria-label
| | string | - | ARIA label for accessibility |
The library is written in TypeScript and includes built-in type definitions.
`tsx`
import type {
CustomCursorProps,
CursorPosition,
CursorOffset,
CursorMoveHandler,
CursorVisibilityHandler,
CursorVisibilityReason,
} from '@yhattav/react-component-cursor';
š Complete TypeScript Reference ā
All prop types, interfaces, and future-ready types with usage examples.
Optional utility functions for advanced SSR scenarios:
`tsx`
import { isSSR, isBrowser, browserOnly, safeDocument, safeWindow } from '@yhattav/react-component-cursor';
Optimized for performance with advanced control for complex use cases.
š Complete Performance Guide ā
Optimization strategies, settings matrix, and advanced techniques.
Works out of the box with Next.js, Gatsby, Remix, and other SSR frameworks.
`tsx
// Zero configuration needed - SSR handled automatically
import { CustomCursor } from '@yhattav/react-component-cursor';
āØ
`
Live Demo: Interactive Examples & Showcase ā
Local Examples (clone and run):
`bashVite React example with multiple cursor demos
cd example && npm install && npm run dev
$3
#### Framework Compatibility
- ā
Next.js - Full SSR support with zero configuration
- ā
Gatsby - Static generation compatible
- ā
Remix - Server-side rendering works out of the box
- ā
Vite/CRA - Client-side rendering with optimal performance
- ā
Astro - Partial hydration compatible
Advanced Usage
$3
`tsx
function ContainerExample() {
const containerRef = useRef(null);
return (
ref={containerRef}
style={{
position: 'relative',
cursor: 'none', // Hide native cursor in this container
}}
>
style={{
width: '40px',
height: '40px',
border: '2px solid #ef4444',
borderRadius: '50%',
}}
/>
{/ Container content /}
$3
`tsx
function InteractiveCursor() {
const [isHovered, setIsHovered] = useState(false);
return (
<>
style={{
width: isHovered ? '60px' : '20px',
height: isHovered ? '60px' : '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
transition: 'all 0.2s ease',
}}
/>
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
Hover me!
>
);
}
`$3
`tsx
function VisibilityAwareCursor() {
const handleVisibilityChange = (isVisible: boolean, reason: string) => {
console.log('Cursor visibility:', isVisible, 'reason:', reason);
// Reason can be: 'container', 'disabled', or other values in future versions
}; return (
style={{
width: '20px',
height: '20px',
backgroundColor: '#3b82f6',
borderRadius: '50%',
}}
/>
);
}
``We welcome contributions! See our guides:
- Contributing Guide - How to contribute
- Development Guide - Complete development setup and workflow
MIT Ā© Yonatan Hattav