GitHub Stars

A repository's GitHub stars, counted up with a filling star and a burst of particles.

<script setup lang="ts">
import {
  GithubStars,
  GithubStarsIcon,
  GithubStarsLogo,
  GithubStarsNumber,
  GithubStarsParticles,
} from '@animate-ui/vue/primitives/github-stars'
import Star from './github-stars-star.vue'
</script>

<template>
  <GithubStars
    username="imskyleen"
    repo="animate-ui"
    :value="3200"
    class="flex items-center gap-2"
  >
    <GithubStarsLogo class="size-6 text-muted-foreground" />
    <div class="flex items-center gap-1 rounded-lg bg-muted px-2 py-1">
      <GithubStarsNumber class="font-medium text-muted-foreground tabular-nums" />
      <GithubStarsParticles class="text-yellow-500">
        <GithubStarsIcon
          :icon="Star"
          class="size-[18px] fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700"
          color="var(--color-yellow-500)"
        />
      </GithubStarsParticles>
    </div>
  </GithubStars>
</template>

Installation

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

Usage

<script setup lang="ts">
import {
  GithubStars,
  GithubStarsIcon,
  GithubStarsLogo,
  GithubStarsNumber,
  GithubStarsParticles,
} from '@animate-ui/vue/primitives/github-stars';
</script>

<template>
  <GithubStars username="imskyleen" repo="animate-ui" class="flex items-center gap-2">
    <GithubStarsLogo class="size-6" />
    <GithubStarsNumber />
    <GithubStarsParticles>
      <GithubStarsIcon :icon="StarIcon" class="size-4" color="gold" />
    </GithubStarsParticles>
  </GithubStars>
</template>

The count is fetched from the GitHub API (api.github.com/repos/<username>/<repo>), unauthenticated. To avoid the request (rate limits, server-side data), pass the count with value.

Animation

  • Once the count is loaded, the number counts up from 0 with rolling digits (Sliding Number).
  • The star fills from the bottom as the number climbs, and bursts into particles when the count is reached.
  • Nothing is rendered until the count is loaded (with as-child, the child is there but hidden); the container is marked aria-busy meanwhile.
  • With in-view, the request waits for the element to be on screen.
  • Under reduced motion, the digits change without rolling and the burst is skipped.

API Reference

GithubStars

PropTypeDefault
as-child?
booleanfalse
username?
string-
repo?
string-
value?
number-
delay?
number0
#default
slot-
in-view?
booleanfalse
in-view-once?
booleantrue
in-view-margin?
string'0px'
...props?
HTMLMotionProps<'div'>-

GithubStarsNumber

The count, as a Sliding Number.

PropTypeDefault
pad-start?
booleantrue
...props?
Omit<SlidingNumberProps, 'number' | 'fromNumber'>-

GithubStarsIcon

Renders the icon twice: empty, and filled as the count climbs.

PropTypeDefault
icon
Component-
color?
string'currentColor'
active-class?
string-
...props?
HTMLAttributes-

GithubStarsParticles

Bursts when the count is reached. Takes the ParticlesEffect props.

PropTypeDefault
#default
slot-
size?
number4
...props?
ParticlesEffectProps-

The GitHub mark, labelled for screen readers. Takes svg props.

useGithubStars

Returns getters for stars, currentStars (the displayed value), isLoading and isCompleted.

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

Last updated: 10/23/2026