# Border Beam

> Gradient beam of light travelling around a card's border.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/border-beam
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/border-beam.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/border-beam-demo.tsx"
import { ArrowUpRight, Zap } from "lucide-react"

import { BorderBeam } from "@/components/border-beam"

export default function BorderBeamDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-6">
      <BorderBeam className="w-80">
        <div className="flex flex-col gap-4 p-6">
          <span className="flex size-10 items-center justify-center rounded-xl bg-orange-500/10 text-orange-500">
            <Zap className="size-5" />
          </span>
          <div>
            <h3 className="font-medium">Pro plan</h3>
            <p className="mt-1 text-sm text-muted-foreground">Unlimited projects, priority builds and team seats.</p>
          </div>
          <a href="#" className="inline-flex items-center gap-1 text-sm font-medium">
            Upgrade now <ArrowUpRight className="size-4" />
          </a>
        </div>
      </BorderBeam>
      <BorderBeam className="rounded-full" colorFrom="#06b6d4" colorTo="#22c55e" duration={4}>
        <span className="flex h-10 items-center px-5 text-sm font-medium">Now in public beta</span>
      </BorderBeam>
    </div>
  )
}
```

## Source

```tsx title="components/border-beam.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

const keyframes = `@keyframes border-beam-spin{to{transform:rotate(1turn)}}`

export interface BorderBeamProps extends React.ComponentProps<"div"> {
  colorFrom?: string
  colorTo?: string
  /** Seconds per lap around the border */
  duration?: number
  /** Border thickness in px */
  borderWidth?: number
  /** Length of the beam, in degrees of the lap */
  beamLength?: number
}

// A conic gradient spins behind the content; the content's background covers
// all of it except a ring the width of the border.
export function BorderBeam({
  colorFrom = "#f97316",
  colorTo = "#a855f7",
  duration = 6,
  borderWidth = 1.5,
  beamLength = 90,
  className,
  children,
  ...props
}: BorderBeamProps) {
  return (
    <div
      className={cn("relative isolate overflow-hidden rounded-2xl bg-border", className)}
      style={{ padding: borderWidth }}
      {...props}
    >
      <style href="border-beam" precedence="default">
        {keyframes}
      </style>
      <div
        aria-hidden
        className="absolute top-1/2 left-1/2 -z-10 aspect-square w-[max(200%,40rem)] -translate-1/2 motion-reduce:hidden"
      >
        <div
          className="size-full"
          style={{
            background: `conic-gradient(from 0deg, transparent 0deg, transparent ${360 - beamLength}deg, ${colorFrom} ${360 - beamLength * 0.6}deg, ${colorTo} 360deg)`,
            animation: `border-beam-spin ${duration}s linear infinite`,
          }}
        />
      </div>
      <div className="relative h-full rounded-[inherit] bg-card text-card-foreground">{children}</div>
    </div>
  )
}
```
