Docs
Starfall

Starfall

A beautiful animated starfall effect component with multiple layers of falling stars.

Starfall

Installation

Copy and paste the following code into your project.

components/ui/starfall.tsx

import { motion } from "framer-motion";
 
interface StarfallProps {
  starCount?: number;
  primaryColor?: string;
  className?: string;
}
 
const Starfall = ({
  starCount = 50,
  primaryColor = "#ffffff",
  className = "",
}: StarfallProps) => {
  const stars = Array.from({ length: starCount }, (_, i) => {
    const starTailLength = Math.random() * 2.5 + 5;
    const topOffset = Math.random() * 100;
    const fallDuration = Math.random() * 6 + 6;
    const fallDelay = Math.random() * 10;
 
    return {
      id: i,
      topOffset,
      fallDuration,
      fallDelay,
    };
  });
 
  return (
    <div
      className={`absolute inset-0 w-full h-full -rotate-45 pointer-events-none ${className}`}
      style={{
        perspective: "1000px",
        transformStyle: "preserve-3d",
      }}
    >
      {stars.map((star) => (
        <motion.div
          key={star.id}
          className={`
            absolute h-[2px] 
            bg-gradient-to-r from-current to-transparent
            rounded-full
            drop-shadow-[0_0_6px_currentColor]
          `}
          style={{
            top: `${star.topOffset}vh`,
            width: "6em",
            color: primaryColor,
            willChange: "transform",
          }}
          initial={{ x: "104em" }}
          animate={{ x: "-30em" }}
          transition={{
            duration: star.fallDuration,
            delay: star.fallDelay,
            repeat: Infinity,
            ease: "linear",
            repeatType: "loop",
          }}
        >
          <div className="relative w-full h-full">
            <div
              className={`
                absolute top-0 left-[calc(-1em)] w-[1em] h-full
                bg-gradient-to-r from-transparent via-current to-transparent
                rounded-inherit animate-blink
              `}
              style={{
                willChange: "transform, opacity",
              }}
            />
            <div
              className={`
                absolute top-0 left-[calc(-1em)] w-[1em] h-full
                bg-gradient-to-r from-transparent via-current to-transparent
                rounded-inherit rotate-45 animate-blink
              `}
              style={{
                willChange: "transform, opacity",
              }}
            />
            <div
              className={`
                absolute top-0 left-[calc(-1em)] w-[1em] h-full
                bg-gradient-to-r from-transparent via-current to-transparent
                rounded-inherit -rotate-45 animate-blink
              `}
              style={{
                willChange: "transform, opacity",
              }}
            />
          </div>
        </motion.div>
      ))}
    </div>
  );
};
 
export Starfall;

Update your globals.css

Add the following animation to your globals.css:

@theme {
 --animate-blink: blink 2s linear infinite;
 
 @keyframes blink {
  50% {
    opacity: 0.6;
  }
 }
 
}

Update the import paths to match your project setup.

import Starfall from "@/components/ui/starfall";

Usage

import Starfall from "@/components/ui/starfall";
 
export default function Example() {
  return (
    <div className="relative h-[500px]">
      <Starfall starCount={30} primaryColor="#6366f1" className="opacity-30" />
    </div>
  );
}

Examples

Multi-layered Effect

Create depth by using multiple Starfall components with different colors and opacities:

<div className="relative h-[500px]">
  {/* Background layer */}
  <Starfall starCount={30} primaryColor="#6366f1" className="opacity-30" />
 
  {/* Middle layer */}
  <Starfall starCount={25} primaryColor="#818cf8" className="opacity-50" />
 
  {/* Foreground layer */}
  <Starfall starCount={20} primaryColor="#ffffff" className="opacity-70" />
</div>

Dark Background

<div className="relative h-[500px] overflow-hidden rounded-xl">
  {/* Deep space background */}
  <div className="absolute inset-0 bg-[#050507]">
    <div className="absolute inset-0 bg-gradient-to-b from-[#0f0f18]/30 via-[#050507] to-black" />
    <div className="absolute inset-0 bg-gradient-to-r from-[#090916]/40 via-transparent to-[#06060f]/40" />
    <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,rgba(15,15,24,0.15),transparent_80%)]" />
  </div>
 
  {/* Starfall effect */}
  <Starfall starCount={30} primaryColor="#ffffff" />
</div>

Props

PropTypeDefaultDescription
starCountnumber50Number of falling stars to display
primaryColorstring"#ffffff"Color of the stars
classNamestring""Additional CSS classes to apply