GlitchButton simulates a corrupted display. Red and cyan ghost copies of the label flicker over a scanline texture. By default the glitch only fires while you hover, but it can also run automatically on a random interval or stay permanently on.

Preview

GlitchButton

Hover to trigger

Variants

The effect is fully prop driven, so you can recolor it, retime it, change what triggers it, and reshape it with className, all without touching the component.

Toxic

Swap the two channel colors with colors.

Toxic

Green / magenta split

Overload

Crank intensity and lengthen the burst for a more violent glitch on hover.

Overload

High intensity on hover

Auto

Set trigger="auto" to fire timed bursts on a random interval without needing a hover. Tune the cadence with glitchInterval.

Auto

Fires on its own

Always on

Set trigger="always" for a permanently corrupted signal.

Always on

Never stops

Clean pill

Drop the scanlines with scanlines={false} and round it off via className.

Clean pill

No scanlines, rounded

Install

Add the item with the shadcn CLI.

npx shadcn@latest add @evilbuttons/glitch-button

Usage

[]txt
import GlitchButton from "@/components/evil-buttons/glitch-button";

export function ButtonDemo() {
  return <GlitchButton>DEPLOY DOOM</GlitchButton>;
}

Props

The component spreads any <button> HTML attributes.

PropTypeDefaultDescription
glitchIntervalnumber3500Base milliseconds between automatic bursts (±20% random jitter). Used when trigger is "auto".
glitchDurationnumber450Duration in milliseconds of a single glitch burst.
colors[string, string]["#ef4444", "#22d3ee"]The two RGB-split channel colors.
intensitynumber1Multiplier on the channel and shake displacement. Higher is more violent.
trigger"auto" | "hover" | "always""hover"When the glitch fires: only on hover, timed bursts, or continuously.
scanlinesbooleantrueToggle the scanline overlay.
classNamestring-Extra classes passed to the button.
childrenReact.ReactNode-The visible button label or content.

Notes

  • Honors prefers-reduced-motion: all motion is suppressed, including trigger="always", and the label stays static.
  • The surface stays a dark "screen" in both themes, because the RGB-split ghosts use mix-blend-mode: screen and only read against a dark base.
  • Keyframes are injected into document.head once on first mount and shared across every instance on the page.

Registry

The registry item includes components/evil-buttons/glitch-button.tsx and installs clsx and tailwind-merge as dependencies. The component imports cn from @/lib/utils.