Skip to content
CURSORKIT

Paste one line. That is the install.

Install

Drop the tag anywhere in your HTML — head or the end of body, it makes no difference. The script waits for the document before it draws anything.

Embed tag
<script src="https://cursor-pts9j3ezj-meetchauhanteam.vercel.app/embed.js?style=magnetic-blob&click=shockwave&color=ff00ff"></script>

The response is assembled per configuration: you get the engine core plus only the style and effect you named, which is typically under 10kb gzipped. Nothing else is downloaded and there is no build step to add.

URL parameters

Every option is a query parameter. Values are clamped and validated server-side and again in the browser, so a bad value degrades to the default rather than breaking your page.

ParameterTypeDefaultMeaning
stylestringdot-ringCursor shape. One of 127 ids.
clickstringripple-cleanClick effect. One of 59 ids.
hoverstringscale-expandHow the cursor reacts to interactive elements.
colorhexffffffPrimary colour, without the leading #.
color2hex= colorAccent colour, used by trails and particles.
size0.4 – 31Size multiplier.
speed0.25 – 31Animation speed multiplier.
opacity0.05 – 11Overall cursor opacity.
blendstringnormalCSS mix-blend-mode for the overlay.
dark0 | 11Hints that the host page is dark.
adapt0 | 11Keep the cursor legible against whatever it is over. Set 0 to pin your exact colour.
motionfullSet to `full` to ignore the reduced-motion preference.
ignoreselectorElements that keep the native cursor.
zinteger2147483000z-index of the overlay canvas.

You can also set any parameter as a data-attribute on the script tag. Attributes win over query parameters, which makes server-side templating easier.

Per-element control

The cursor classifies what it is over automatically — links, buttons, inputs, and media all get sensible treatment with no markup from you. When you want something specific, annotate the element.

data-cursor="native"Restores the operating system cursor over this element.
data-cursor="text"Treats the element as text, whatever its tag.
data-cursor="button"Treats the element as interactive.
data-cursor="image"Treats the element as media.
data-cursor="anything-else"Marks a custom target, and doubles as its label.
data-cursor-label="View"Overrides the automatically detected label.
data-cursor-color="#ff0055"Overrides the cursor colour while hovering this element.

Labels write themselves

Any transform that shows a label — label, label-chip, caption, typewriter — reads the text off the element itself. A button that says “Add to cart” shows “Add to cart”. You do not annotate anything.

The order below mirrors how a screen reader computes an accessible name, for the same reason: it is what the element genuinely calls itself. Markup that is good for assistive technology is markup that labels well here, and vice versa.

1data-cursor-labelYour explicit override. Always wins.
2aria-labelWhat the element already announces itself as.
3aria-labelledbyResolved and joined, same as a screen reader would.
4titleThe native tooltip text.
5altFor images, or an image inside the element.
6placeholderFor inputs with no other name.
7visible textTrimmed and truncated on a word boundary at 28 characters.
8the element type“Link”, “Button”, “View”, “Type” — so a label is never empty.

Elements marked data-cursor="native" are skipped entirely — they get no label and no cursor.

It reads the page and adapts

The most common way a custom cursor fails is not ugliness — it is a white cursor crossing onto a white hero and disappearing. No style can solve that on its own, because a style cannot know what it is over.

So the engine reads the page underneath the pointer and shifts the cursor colour until it has at least 3:1 contrast against it. Only lightness moves; hue and saturation are kept. Your magenta stays magenta — it just gets lighter or darker so it can still be seen.

  • How it readselementFromPoint, then a walk up the ancestors compositing every translucent background until it hits an opaque one. Computed styles, not pixels — no screen capture, no permission prompt, no 200kb dependency.
  • Over images and gradientsIt says so rather than guessing. Styles that care fall back; the rest keep your configured colour.
  • CostThrottled to roughly ten reads a second, and only when the pointer has actually travelled. The contrast solve is cached on the colour pair.
  • Turning it offadapt=0 pins your exact colour. Worth it when the cursor is part of a fixed brand treatment and you control the backgrounds.

The neumorphic styles take this further and use the sampled colour as their own fill, because soft UI only works when the shape matches the surface it sits on. That is what lets them work on any page rather than one exact background.

Hover transforms

A hover transform composes with any style rather than replacing it, which is why the combination count is what it is.

none
The cursor ignores what it is over. Styles may still react on their own.
scale-expand
The whole cursor scales up over anything interactive.
scale-contract
The cursor tightens down instead of growing. Reads as focus.
magnet
The cursor is drawn toward the centre of whatever it is over.
invert
A difference-blended disc takes over on hover, inverting what is beneath.
label
Shows the element’s `data-cursor-label` in a pill beside the cursor.
outline
Traces a rounded box around the hovered element as you arrive.
hide
The cursor withdraws entirely, leaving the element to speak for itself.
scale-grow
Doubles the cursor. The most obvious possible signal that something is live.
squash
Flattens the cursor horizontally, like it is being pressed against glass.
spin
Rotates the whole cursor a half turn as it arrives on a target.
tilt
Skews the cursor as though it were lying on a surface seen at an angle.
jitter
Vibrates the cursor while it sits over something clickable.
lift
Raises the cursor and drops a soft shadow beneath it.
ring-pulse
Emits a continuous ring while you rest on a target.
crosshair
Extends full-height and full-width guides across the viewport.
corners
Puts registration corners on the element, ignoring the cursor entirely.
underline
Sweeps a rule along the bottom of whatever you are pointing at.
highlight
Washes a translucent marker stripe over the element, like a highlighter.
label-chip
A square-cornered chip naming the element, read from its own content.
label-below
Sets the element’s name underneath it, centred, like a photo caption.
typewriter
Types the element’s name out one character at a time beside the cursor.
readout
Prints the hovered element’s pixel dimensions, like a design tool.
spotlight
Darkens the whole page except a circle around the pointer.
tether
Draws a line from the cursor to the centre of the element it is over.
orbit
Sends three satellites into orbit around the cursor while it is on target.
sparkle
Scatters small stars around the pointer over anything interactive.
hard-shadow
Casts a flat offset shadow behind the cursor. Pairs with brutalist styles.
magnet-strong
Snaps hard to the centre of the target. Almost impossible to miss a click.

Runtime API

The script publishes a small global. Use it to change the cursor after load — on a theme switch, or per route.

CursorKit.update({ style: 'comet', color: '00ffcc' });
CursorKit.destroy();                  // restore the native cursor
CursorKit.boot({ style: 'dot-ring' }); // start again

CursorKit.engine        // the live Engine instance, or null
CursorKit.allStyles()   // every style loaded in this bundle

A per-config embed only contains the style and effect you asked for. To switch between many at runtime, load /embed.full.js instead — the whole library in one file.

Frameworks

Next.js — App Router

// app/layout.tsx
import Script from 'next/script';

<Script
  src="https://cursor-pts9j3ezj-meetchauhanteam.vercel.app/embed.js?style=dot-ring&color=ffffff"
  strategy="afterInteractive"
/>

React — Vite or CRA

// index.html, before </body>
<script src="https://cursor-pts9j3ezj-meetchauhanteam.vercel.app/embed.js?style=goo&click=ink-splat"></script>

Webflow / Squarespace / WordPress

Paste into the custom-code or header-injection field:

<script src="https://cursor-pts9j3ezj-meetchauhanteam.vercel.app/embed.js?style=ribbon&color=ff8a3d"></script>

What it does on its own

  • Touch devicesThe script exits before drawing and leaves the native cursor alone. Nothing is hidden and no canvas is created.
  • Reduced motionTrails, particles and magnetism are dropped; the cursor shape stays. Override with motion=full if your use case genuinely needs it.
  • Background tabsThe render loop stops on visibilitychange and restarts with a fresh clock, so returning to a tab never plays a backlog of frames.
  • ErrorsIf a style throws, the engine tears itself down and restores the native cursor. A visitor is never left without a pointer.