Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Charts & Stats

Animated Counter

Charts & Stats

Animated Counter React chart component for Tailwind CSS v4

Virtual ListArea chart
Live props
Content
decimals0
padStart1
separator
decimalSeparator
locale
grouping
Behavior
duration0.6s
bounce0.18
Appearance
size
font
weight
color
fade
fadeSize22%
Code
import { AnimatedCounter } from "@/components/ui/animated-counter"

<AnimatedCounter />
  1. Home
  2. Components
  3. Charts & Stats
  4. Animated Counter
Free

Animated Counter React chart component for Tailwind CSS v4

v1.0.1·Updated in 1.2.1

A React animated counter that rolls each digit to its new value like an odometer, for stats, prices, timers and live numbers.

Drag along the ruler, or focus it and use the arrow keys, to change the value. Digits roll up as the number grows and back down as it shrinks, fading in and out at the top and bottom of each window rather than being cut off. A number that keeps changing spins instead of stuttering. The width always matches the number: a place that is gained slides in, one that is lost fades out while the rest close up, and the separators glide along with them.

Animated Counter is a free React chart component in the React chart and stat components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add animated-counter, together with Motion presets and UIProvider and the npm package motion.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add animated-counter

Usage

Import AnimatedCounter from @/components/ui/animated-counter.

"use client"

import { AnimatedCounter } from "@/components/ui/animated-counter"

export function Revenue({ total }: { total: number }) {
  return <AnimatedCounter value={total} size="lg" weight="medium" />
}

// money: two decimals and a currency mark that stays put
// <AnimatedCounter value={total} decimals={2} prefix={<span>₹</span>} grouping="indian" />

// fixed width, so a timer never shifts as it rolls over
// <AnimatedCounter value={seconds} padStart={4} separator="" />

Props

  • value*
    number

    The number to show. Each change animates from whatever is on screen, so it can be updated as often as you like. Negative values get a leading minus.

  • decimalsdefault 0
    number

    How many decimal places to keep, up to 15. The value is rounded to that precision, so the wheels always land on a whole digit.

  • durationdefault 0.6
    number

    Roughly how many seconds a digit takes to settle on its new face. Lower it when the value updates continuously, so the wheels stay close to the number.

  • padStartdefault 1
    number

    Fewest whole digits to show, up to 24, padded with leading zeros. Use it to hold the width steady when the number crosses a power of ten.

  • separatordefault ","
    string

    Placed between digit groups. Pass an empty string to group nothing.

  • decimalSeparatordefault "."
    string

    Character between the whole and decimal digits.

  • localedefault ""
    string

    Intl locale whose group and decimal marks replace separator and decimalSeparator, unless you pass those: "en-US" writes 1,234.5, "de-DE" 1.234,5, "fr-FR" 1 234,5. Falls back to UIProvider's locale; empty keeps the separators.

  • groupingdefault "western"
    "western" | "indian"

    Where the separators land. Western groups every three digits, 1,234,567. Indian groups the last three then pairs, 12,34,567.

  • sizedefault "inherit"
    "inherit" | "sm" | "md" | "lg" | "xl"

    Font size: 24px (sm), 36px (md), 60px (lg) or 72px (xl). Inherit takes the size of the surrounding text, so a text class on the counter or its parent sizes it instead.

  • fontdefault "inherit"
    "inherit" | "sans" | "mono" | "serif"

    Font family from your theme tokens. Figures are tabular in every family, so the width only changes when a place is gained or lost.

  • weightdefault "inherit"
    "inherit" | "normal" | "medium" | "semibold" | "bold"

    Font weight of the digits, the separators and any string prefix or suffix.

  • colordefault "currentColor"
    string

    Text color, any CSS color. currentColor follows the surrounding text, so it adapts to light and dark on its own.

  • fadedefault true
    boolean

    Fades each digit window at its top and bottom edge, so rolling faces blur in and out. Turn it off for a hard cut like a mechanical counter.

  • fadeSizedefault 22
    number

    How deep the top and bottom fade of each digit reaches, as a percent of the line box. Only with fade on.

  • bouncedefault 0.18
    number

    Spring bounce of the wheels and the width changes, from 0 (settles with no overshoot) to 1.

  • prefix
    ReactNode

    Rendered before the number, for a currency mark or an icon. It sits outside the wheels and never animates, but glides when the width changes.

  • suffix
    ReactNode

    Rendered after the number, for a unit or a percent sign.

  • className
    string

    Extra classes merged onto the root element (data-slot="animated-counter"). With size, font and weight left on inherit it styles like text, so a text class here or on a parent works too. The digit columns carry data-slot="animated-counter-digit" and the separators data-slot="animated-counter-mark", for reaching either from the root.

Examples

Revenue card

Two decimals and a dollar prefix; add an order and the total rolls up while the order count ticks along.

Live value

A shorter duration keeps the wheels close to a number that updates every second or so.

Countdown timer

padStart 2 and no separator hold minutes and seconds at a fixed width.

Locales and grouping

locale picks the group and decimal marks; grouping indian puts separators after the last three digits, then every two.

Dependencies

motionmotionui-config

Files

  • components/ui/animated-counter.tsx

FAQ

Is the React Animated Counter chart component free?

Yes. The source is free and needs no account: copy it from the Code tab or install it with the CLI.

How do I install Animated Counter?

Run npx wingo-ui@latest add animated-counter. It also adds the Wingo UI items it builds on (Motion presets and UIProvider) and the npm package motion. With shadcn, run npx shadcn@latest add https://wingo-ui.com/r/animated-counter.json.

See also

Stat CardNumber formatlibCountdownTrend badgeKPI Dashboard

Used in

Stat CardCountdownPriceStats SectionAffiliate PageAI Product PageBug Bounty PageCompare PageDevelopers PageImpact PageLanding PagePromo Page

and 5 more.

More React chart and stat components

Radial barTrackerHeatmap calendarSparklineLeaderboardArea chart
All 16 React chart and stat components

Articles using this component

  • React Animated Number Counter: Rolling Odometer Digits

    Component guides · Oct 19, 2026 · 9 min read

  • Magic UI Alternatives: 5 Animated React Libraries Compared

    Comparisons and alternatives · Oct 16, 2026 · 11 min read

PreviousVirtual ListNext Area chart
$12,480012345678901234567890012345678901234567890,012345678901234567890012345678901234567890012345678901234567890