Overlays & Feedback

Smooth Follow Cursor

A spring-physics custom cursor with a deforming blob follower.

A custom cursor driven by spring physics: the center dot sticks to the fingertip while the outer ring converges behind it, stretching and deforming along the direction of travel according to cursor speed to produce a "soft-bodied" trailing tail.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add smooth-follow-cursor.en

New project or installation trouble? Start here →

Smooth Follow Cursor is a React custom cursor component built with Tailwind CSS and Motion springs. Wrap a section with it and the native cursor inside is replaced by a center dot plus a trailing ring; pressing the mouse button shrinks the ring and enlarges the dot.

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

38
7
0.4
Active edited usageDefault props
<SmoothFollowCursor/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

When to use

  • Hero area of a portfolio or design studio homepage, where the cursor itself is part of the interaction feedback.
  • Hero section of a product launch or event page, paired with large headings on a dark background.
  • Browsing-oriented blocks such as interactive showcases or project walls with few form fields.
  • Not a good fit: forms, text editors or dashboards that need precise clicking, where the native cursor works better. If you only want one button to feel magnetic, use Magnetic Button instead.

Installation

npx webberui@latest add https://webberui.com/r/smooth-follow-cursor.en.json

Or, once registries are configured in components.json, install it as @webberui/smooth-follow-cursor.

Usage

import { SmoothFollowCursor } from "@/components/ui/smooth-follow-cursor";

<SmoothFollowCursor color="#8b5cf6" blend className="relative h-[340px] w-full">
  {/* your content */}
</SmoothFollowCursor>;

The cursor effect only applies inside this container: the container applies cursor-none to hide the native cursor, which comes back as soon as you leave. Touch devices (pointer: coarse) disable it automatically and keep the native cursor.

Examples

Enable it only in the hero

The effect only applies inside the wrapped container, so wrap the homepage hero and the rest of the page keeps the native cursor.

import { SmoothFollowCursor } from "@/components/ui/smooth-follow-cursor";

export function Hero() {
  return (
    <SmoothFollowCursor className="relative flex min-h-[70vh] items-center justify-center bg-neutral-950">
      <h1 className="text-5xl font-semibold text-white">Brand design and web development</h1>
    </SmoothFollowCursor>
  );
}

Mixed light and dark backgrounds with blending

blend puts the cursor layer on mix-blend-difference, so it stays visible over both black and white areas.

<SmoothFollowCursor blend color="#ffffff" dotColor="#ffffff" className="relative h-96 w-full">
  <div className="grid h-full grid-cols-2">
    <div className="bg-white" />
    <div className="bg-black" />
  </div>
</SmoothFollowCursor>

A minimal ring cursor without deformation

deform={false} turns off velocity stretching; with a smaller size and dotSize you get a plain trailing ring.

<SmoothFollowCursor
  deform={false}
  size={24}
  dotSize={4}
  color="#0ea5e9"
  dotColor="#0ea5e9"
  className="relative h-80 w-full"
>
  {/* your content */}
</SmoothFollowCursor>

Props

PropTypeDefaultDescription
colorstring"#6366f1"Blob outer ring color
dotColorstring"#6366f1"Center dot color
sizenumber38Outer ring diameter (px)
dotSizenumber7Center dot diameter (px)
deformbooleantrueWhether to stretch and deform along the direction of travel by speed
stretchnumber0.4Maximum stretch amount (0–1)
blendbooleanfalseInverts and blends colors with mix-blend-difference
childrenReactNode—Container content

Accessibility

  • When the user has "reduce motion" enabled at the system level, the custom cursor is disabled and the native cursor is kept
  • Touch devices disable it automatically, and overflow-hidden makes sure the outer ring cannot spill out of the container while deforming
  • The cursor layer is a purely visual overlay carrying aria-hidden and pointer-events-none, so it does not affect interaction with the layer underneath

FAQ

Does it work with the Next.js App Router?

Yes. The file starts with "use client", so import it from a Server Component page as usual. The first render matches the server output, and the reduced-motion check only runs after mount, so it does not cause a hydration mismatch.

Can I apply it to the whole site?

It only takes effect inside its own container and applies overflow-hidden to that container. You can wrap your outermost layout for a full-page effect, but keep in mind that overflow-hidden affects sticky or overflowing content inside it.

What format should color use?

When blend is off, the ring's background is color with 1a appended as alpha, so use a 6-digit hex value such as #8b5cf6. With blend on, the ring background uses color directly.

How do I tune the stretch?

stretch sets the maximum stretch (0–1, default 0.4); higher values give a softer tail. deform={false} disables deformation entirely.

What happens on touch devices and with reduced motion?

Only mouse pointers drive the cursor layer, and touch devices (pointer: coarse) keep the native cursor. When the system "reduce motion" setting is on, the component renders a plain container with your content and no custom cursor.