Halo Cursor
A GPU cursor trail shipping four presets — aurora, neon, ripple and sparks — alongside a generic component, a React hook, and an imperative mount function for non-React use. Colour, size and trail length are configurable per preset.
Included with membership
Members install Halo Cursor with one command and get the full source, the usage code and the Framer remix, licensed for client work. One membership covers the whole library and the CLI.
When to use it
A site-wide signature — mount it once near the root and it follows the pointer everywhere. Four presets ship with it, and the preset is the decision that matters; the props only tune it. Because it replaces something the operating system already draws, treat it as a commitment for the whole site rather than one page.
- Mount exactly one, high in the tree, so it survives navigation instead of restarting on every route.
- Start from a preset and adjust from there — the presets carry their own size and trail defaults.
- Leave the native cursor visible over anything clickable, or people lose the affordance they rely on.
Avoid:
- Do not mount more than one. Each opens its own drawing surface and they stack, which shows as a doubled trail and a halved frame rate.
- Do not hide the native cursor on a site with forms. A shader blob gives no indication of what is focused or editable.
- Do not mount it per-page. Every route change tears down the surface and builds a new one, which stutters at exactly the moment the page is busiest.
Props
A cursor trail drawn on the GPU, in four flavours. It replaces the native pointer with a shader that paints where you have just been — a soft aurora ribbon, a neon streak, spreading rings, or sparks. Mount it once near the root of your app; it draws over everything and takes no layout space.
Shared Props
Common to all exported components in this suite.
| Prop | Type | Default | Description |
|---|---|---|---|
color | string | [number, number, number] | "#7EACB5" | Trail colour, as a hex string or three 0–1 channel values. An unparseable value falls back to the default rather than throwing. |
size | number | the preset's own size | Radius of the cursor head in pixels. Each preset carries its own default — 16 aurora, 18 neon, 24 ripple, 20 sparks. |
trail | number | the preset's own trail | How long the trail lingers, 0–1. Defaults are 0.35 aurora, 0.52 neon, 0.68 ripple, 0.62 sparks. Note that aurora pins this to 0.35 and ignores the value you pass. |
<HaloCursor />
The cursor itself. Renders no DOM of its own — it mounts a full-viewport canvas and returns null, so drop it anywhere in the tree.
| Prop | Type | Default | Description |
|---|---|---|---|
preset | HaloCursorPreset | auroraCursor | Which shader to draw with. Pass one of the four exported presets, or your own object of the same shape. |
params | [number, number, number, number] | [0, 0, 0, 0] | Four spare values handed straight to the shader. The bundled presets ignore them; they exist for a custom preset to use. |
hideNativeCursor | boolean | true | Hides the system pointer document-wide while the cursor is active. Set it to false to keep both. Only an explicit false disables it. |
zIndex | number | 9999 | Stacking order of the canvas. Raise it if a fixed overlay covers the trail. |
disableAdaptiveQuality | boolean | false | Keeps the cursor at full resolution on every device. By default the runtime pins the pixel ratio to 1 on the most constrained tier, which softens the trail. This does not affect the reduced-motion and coarse-pointer checks — the cursor still declines to mount at all in either case. |
Presets
| Preset | Description | Key Overrides |
|---|---|---|
"auroraCursor" | A soft, wide ribbon that drifts behind the pointer. | size=16trail=0.35 (fixed) |
"neonCursor" | A tight, bright streak with a hard core. | size=18trail=0.52 |
"rippleCursor" | Rings that spread outward from where you move. | size=24trail=0.68 |
"sparksCursor" | Small particles that scatter and fade. | size=20trail=0.62 |
<AuroraCursor />
HaloCursor with the aurora preset already applied. Same for NeonCursor, RippleCursor and SparksCursor — each accepts only colour, size and trail.
<useHaloCursor />
hookThe hook behind the component. Returns `{ active }` so you can tell whether the cursor actually mounted — it will be false on touch devices and under reduced motion. Options are read once, on mount; later changes are ignored.
| Prop | Type | Default | Description |
|---|---|---|---|
options | HaloCursorOptions | {} | The same options HaloCursor takes. |
<mountHaloCursor />
Imperative entry point for non-React code. Returns a handle with `active`, `setOptions()` and `destroy()`. Unlike the hook, setOptions updates a live cursor.
| Prop | Type | Default | Description |
|---|---|---|---|
options | HaloCursorOptions | {} | The same options HaloCursor takes. |