Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Buttons

Pro

Shimmer Button for React

A button framed by a thin ring that a glint of light keeps running across. For React with Base UI, when one call to action should feel quietly alive.

Framework
UI library

A thin ring frames the Shimmer Button, and every few seconds a glint of light runs across it, catching the top and bottom edges as it passes. On hover the button lifts a little, and it sinks when pressed.

Use it for one premium action, Get early access or Upgrade, where steady, quiet motion draws the eye without flashing. For light that only answers a hover, use the Shine Button instead. It wraps the Button, so every variant and size works. The glint is a strip of light sliding under the ring, a CSS keyframe animation the install adds to your stylesheet, with no animation library; with reduced motion the ring stays, the glint stands still and the button doesn't grow.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { ShimmerButton } from "@/components/ui/shimmer-button";
<ShimmerButton>Get early access</ShimmerButton>

Demos

Color

ringColor is the ring at rest and shimmerColor the glint, each any CSS color. By default the ring is the primary color blended a little toward the page, and the glint is light in both color schemes. Here an outline button gets a border-colored ring with a primary glint, and a filled one a ring in the full primary color.

Preview width

Duration

duration is one cycle in milliseconds, the glint's run plus the pause before the next one; the default is 3000. A short cycle feels restless, so keep it for small buttons; a long one suits a large hero button.

Preview width

Accessibility

The ring is decoration and hidden from assistive tech: the button is announced and activated as any Button. Keyboard focus lifts it as hover does. The glint loops while the button is on screen, so the system's reduced-motion setting stops it.

Enter
Activate the button.
Space
Activate the button.

FAQ

Does the shimmer run all the time?

Yes, the glint runs once per duration for as long as the button is on screen, unless the system asks for reduced motion.

Will a constant animation slow the page down?

No. The glint is a strip moved with translate under a ring mask, which the browser can hand to the compositor: no layout, no re-render and no JavaScript while it runs.

How do I match my brand?

The fill follows variant, and the ring and glint follow ringColor and shimmerColor, which take theme variables such as var(--primary) or any CSS color. The Color demo shows two combinations.

What happens on hover and press?

It grows to 103% on hover or keyboard focus, with a little spring as it settles, and sinks back a little while pressed, as every Button does.

Which way does the glint run in a right-to-left layout?

Right to left, the direction the page reads.

What happens with reduced motion?

The ring stays, with the glint standing still on it, and the button doesn't grow on hover. A press still gives the usual small scale feedback.

API Reference

ShimmerButton

data-slot="shimmer-button-ring"

PropType
children?ReactNode

The label, above the ring.

duration?number

How long one pass of light around the ring takes, in milliseconds, pause included.

Default
3000
focusableWhenDisabled?boolean

Whether the button should be focusable when disabled.

Default
false
nativeButton?boolean

Whether the component renders a native <button> element when replacing it via the render prop. Set to false if the rendered element is not a button (for example, <div>).

Default
true
ringColor?string

The ring's color at rest, any CSS color. By default the primary color, blended a little toward the text so the ring stands apart from the fill.

shimmerColor?string

The light that runs along the ring, any CSS color. By default the page's background in light mode and its text color in dark mode, so it reads as light in both.

render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

CSS variableType
--shimmer-button-durationstring

One pass of the glint, pause included (3s).

--shimmer-button-glintstring

The light that runs along the ring.

--shimmer-button-ringstring

The ring's color at rest.

All 35 buttons