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-beamUsage
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
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | required | Button label. |
| href | string | undefined | Renders a real anchor when set; otherwise a real button. |
| speed | number | 3 | Seconds the beam takes for one full orbit of the border. |
| className | string | undefined | Additional 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.