GitHub Stars Button

A button showing a repository's GitHub stars, counted up with a filling star.

"use client"

import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "cn"
import {
  GitHubStarsButton,
  GitHubStarsButtonIcon,
  GitHubStarsButtonLogo,
  GitHubStarsButtonNumber,
  GitHubStarsButtonParticles,
  githubStarsButtonVariants,
} from "@/components/animate-ui/buttons/github-stars"
import { StarIcon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"

const starVariants = cva("size-[18px]", {
  variants: {
    variant: {
      default:
        "fill-neutral-700 stroke-neutral-700 dark:fill-neutral-300 dark:stroke-neutral-300",
      accent:
        "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
      outline:
        "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
      ghost:
        "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
    },
  },
  defaultVariants: {
    variant: "default",
  },
})

function Star(
  props: Omit<React.ComponentProps<typeof HugeiconsIcon>, "icon">
) {
  return (
    <HugeiconsIcon
      icon={StarIcon}
      strokeWidth={2}
      {...props}
      className={cn("[&_path]:[stroke:inherit]", props.className)}
    />
  )
}

export default function GitHubStarsButtonDemo({
  variant = "default",
  size = "default",
}: VariantProps<typeof githubStarsButtonVariants>) {
  return (
    <GitHubStarsButton
      username="imskyleen"
      repo="animate-ui"
      value={3200}
      asChild
      variant={variant}
      size={size}
    >
      <a
        href="https://github.com/imskyleen/animate-ui"
        target="_blank"
        rel="noreferrer noopener"
      >
        <GitHubStarsButtonLogo />
        <GitHubStarsButtonNumber className="tabular-nums" />
        <GitHubStarsButtonParticles className="text-yellow-500">
          <GitHubStarsButtonIcon
            icon={Star}
            className={starVariants({ variant })}
            color="var(--color-yellow-500)"
          />
        </GitHubStarsButtonParticles>
      </a>
    </GitHubStarsButton>
  )
}

Installation

npx shadcn@latest add @animate-ui/buttons-github-stars
pnpm dlx shadcn@latest add @animate-ui/buttons-github-stars
yarn dlx shadcn@latest add @animate-ui/buttons-github-stars
bun x shadcn@latest add @animate-ui/buttons-github-stars

Usage

import {
  GitHubStarsButton,
  GitHubStarsButtonIcon,
  GitHubStarsButtonLogo,
  GitHubStarsButtonNumber,
  GitHubStarsButtonParticles,
} from '@/components/animate-ui/buttons/github-stars';

export function Stars() {
  return (
    <GitHubStarsButton username="imskyleen" repo="animate-ui" asChild>
      <a href="https://github.com/imskyleen/animate-ui">
        <GitHubStarsButtonLogo className="size-4" />
        <GitHubStarsButtonNumber />
        <GitHubStarsButtonParticles className="text-yellow-500">
          <GitHubStarsButtonIcon icon={StarIcon} color="gold" />
        </GitHubStarsButtonParticles>
      </a>
    </GitHubStarsButton>
  );
}

A button built on GitHub Stars: its parts are GitHub Stars' (GithubStarsLogo, GithubStarsNumber, GithubStarsIcon, GithubStarsParticles), exported here under the button's name. The count is fetched from the GitHub API (api.github.com/repos/<username>/<repo>), unauthenticated; pass it with value to skip the request.

Animation

  • The button stays hidden (visibility: hidden, aria-busy) until the count is loaded. Then the number counts up from 0 with rolling digits (Sliding Number), the star fills from the bottom as it climbs, and bursts into particles when the count is reached.
  • Pressing scales the button to tapScale (0.97), on Motion's spring for scale (stiffness: 550, damping: 30). It doesn't scale on hover, unless you set hoverScale.
  • <AnimateUIProvider tempo> paces the press spring.
  • Under reduced motion, the digits change without rolling, the burst is skipped and the button doesn't scale.

API Reference

GitHubStarsButton

PropTypeDefault
variant?
'default' | 'accent' | 'outline' | 'ghost' | null'default'
size?
'default' | 'sm' | 'lg' | null'default'
username?
string-
repo?
string-
value?
number-
delay?
number0
inView?
booleanfalse
inViewOnce?
booleantrue
inViewMargin?
string'0px'
hoverScale?
number1
tapScale?
number0.97
transition?
Transition{ type: 'spring', stiffness: 550, damping: 30, restSpeed: 10 }
asChild?
booleanfalse
...props?
HTMLMotionProps<'button'>-

GitHubStarsButtonLogo, GitHubStarsButtonNumber, GitHubStarsButtonIcon, GitHubStarsButtonParticles

The parts of GitHub Stars: GithubStarsLogo, GithubStarsNumber, GithubStarsIcon and GithubStarsParticles.

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page