Gradient Border Button

A rainbow gradient endlessly rotates around the button edge.

Installation

  1. Install the dependencies

    $ npm i motion lucide-react
  2. Copy the source into components/ui/gradient-border-button.tsx

    components/ui/gradient-border-button.tsx
    "use client";
    
    import { motion } from "motion/react";
    import { Sparkles } from "lucide-react";
    import type { ButtonHTMLAttributes } from "react";
    
    type GradientBorderButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
      /** Seconds per full rotation of the border gradient */
      speed?: number;
    };
    
    export function GradientBorderButton({ children, className = "", speed = 3, ...props }: GradientBorderButtonProps) {
      return (
        <button className={`group relative inline-flex overflow-hidden rounded-full p-[1.5px] transition-transform hover:-translate-y-0.5 ${className}`} {...props}>
          <motion.span
            aria-hidden
            className="absolute left-1/2 top-1/2 aspect-square w-[300%] bg-[conic-gradient(from_0deg,#3b82f6,#8b5cf6,#ec4899,#f59e0b,#3b82f6)]"
            style={{ x: "-50%", y: "-50%" }}
            animate={{ rotate: 360 }}
            transition={{ duration: speed, repeat: Infinity, ease: "linear" }}
          />
          <span className="relative inline-flex items-center gap-2 rounded-full bg-white px-6 py-3 text-sm font-medium text-zinc-900 transition-colors group-hover:bg-zinc-50">
            {children}
          </span>
        </button>
      );
    }
    
    export default function Demo() {
      return (
        <GradientBorderButton>
          <Sparkles className="size-4 text-violet-600" />
          Try Kinetiq Pro
        </GradientBorderButton>
      );
    }
    
  3. Use it

    The file exports the component and a Demo showing typical usage. Import whichever you need.