Turn any React icon into your cursor. A ghost. A rocket. A sword. Your call.
A tiny hook that takes a React icon, converts it into an SVG data URL, and injects it into CSS as a cursor.
No canvas hacks. No external assets. Just React → SVG → cursor.
npm install react-icon-cursor react-iconsimport { useReactIconCursor } from 'react-icon-cursor';import { FaGhost } from 'react-icons/fa6';const config = {
body: {
icon: FaGhost,
size: 24,
style: { color: '#60a5fa' },
hotspot: 'topLeft',
fallback: 'auto',
},
};useReactIconCursor(config);Each selector maps to a cursor config.
{
selector: {
(icon, size, style, hotspot, fallback);
}
}Any valid CSS selector.
'*'; // everything
'button'; // only buttons
'.card'; // class
'#app'; // idA React icon component.
import { FaRocket } from 'react-icons/fa6';
icon: FaRocket;Pixel size of the cursor.
size: 32;Inline styles applied to the icon.
style: {
color: '#ff0000';
}You can pass any style attributes that static svgs support:
- color
- fill
- stroke
- strokeWidth
- opacity
- transform
- transformOrigin
- transformBox
- filter
Controls the actual click point.
You can use:
topLeft;
top;
topRight;
left;
center;
right;
bottomLeft;
bottom;
bottomRight;hotspot: [10, 10];Fallback cursor if something fails.
fallback: 'auto';You can scope different cursors to different elements.
const config = {
'*': {
icon: FaGhost,
},
button: {
icon: FaHandPointer,
fallback: 'pointer',
},
};- React icon → rendered to static SVG
- SVG → encoded into data URL
- CSS injected into
<style>tag - Browser uses it as cursor
- Very large sizes can look blurry depending on the browser
- Some browsers clamp cursor size
- If your cursor is not updating, check selector specificity
- Animations do not work (cursor images are always static)
- Layout styles like
margin,padding,positionare ignored background/backgroundColorwon’t apply- Styles may not override icons with hardcoded
fill/stroke - External CSS cannot target the SVG (it’s a data URL)
- Transforms may need
transformBox: 'fill-box'for consistency
Because default cursors are boring.
And because React icons are already in your bundle, so why not reuse them in the weirdest possible way.
If you end up shipping a production app where users have a sword as a cursor, that’s on you lol.
