Skip to content
Template Empire / components

Search components

10 results

Browse components

Border Beam Button

A free animated border button for React and Next.js: a beam of light orbits the button's edge on a masked conic gradient.

  • Automated axe check
  • Reduced-motion tested
  • SSR build verified
  • CSS and React
  • No runtime packages

Border Beam Button is a free animated border button for React and Next.js, built with pure CSS and styled with Tailwind. A light beam orbits the pill's one-pixel border once every 3 seconds by default: a conic gradient fading from the accent colour to transparent, masked to the border ring, spun by a CSS keyframe that rotates an @property-registered angle. Only the gradient angle animates, there is no JavaScript animation loop, and the component renders on the server.

Because the beam lives in an edge-only masked layer, the button face stays clean and the label keeps identical contrast at every beam position. It renders a real anchor when you pass href and a real button otherwise. Hovering or keyboard-focusing the control brightens the beam and nudges the label up one pixel, and the focus-visible ring is a separate outline so focus never depends on colour alone. Under prefers-reduced-motion the orbit stops and the border shows the same gradient at a fixed angle, applied by a CSS media query.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/btn-border-beam

Usage

import { BtnBorderBeam } from "@/components/btn-border-beam";

export default function Page() {
  return (
    <div className="flex items-center gap-2">
      <BtnBorderBeam href="/pricing">See pricing</BtnBorderBeam>
      <BtnBorderBeam speed={6}>Watch the demo</BtnBorderBeam>
    </div>
  );
}

Props

PropTypeDefaultDescription
childrenReactNoderequiredButton label.
hrefstringundefinedRenders a real anchor when set; otherwise a real button.
speednumber3Seconds the beam takes for one full orbit of the border.
classNamestringundefinedAdditional classes merged onto the control.

Customisation

Border Beam Button exposes one component token: btn-beam-color sets the beam colour and defaults to the accent design token, so retheming your accent rethemes the beam. Set the orbit time with the speed prop and restyle the pill itself from the className prop:

<BtnBorderBeam href="/pricing" speed={5} className="px-8 text-base">
  See pricing
</BtnBorderBeam>

/* retheme the beam via the component token */
:root {
  --btn-beam-color: var(--color-brand-400);
}

Frequently asked questions

Is Border Beam Button free for commercial use?
Yes. Border Beam Button is MIT licensed, so you can use it in personal and commercial projects without attribution.
Does the border beam hurt performance or accessibility?
No. The beam is pure CSS: a keyframe rotates a registered custom property that drives a conic gradient masked to the one-pixel border ring, so there is no JavaScript animation loop, no layout work, and no React renders while it plays. The layer is aria-hidden and ignores pointer events, the control is a real anchor or button named by its label, and the focus-visible ring is a separate outline rather than the beam. Under prefers-reduced-motion the orbit stops and a static gradient border renders instead.
How do I change the beam colour or speed?
Set the speed prop to the number of seconds one orbit should take, which defaults to 3. For colour, override the btn-beam-color token from your stylesheet; it defaults to your accent design token, so the beam follows your theme automatically. There is deliberately no colour prop, keeping theming in tokens.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates