Join our Discord Community

React useCounter Hook

React useCounter hook for numeric state management. Increment, decrement, and reset controls with TypeScript support for Next.js applications.

Tired of writing the same counter logic repeatedly?

Join our Discord community for help from other developers.


Ever find yourself writing const [count, setCount] = useState(0) and then creating increment = () => setCount(c => c + 1), decrement = () => setCount(c => c - 1), and reset = () => setCount(0) functions? You know the drill—same boilerplate for every counter, shopping cart quantity, or score tracker. This free open source React useCounter custom hook handles all that numeric state management so you can focus on your app logic instead of writing the same counter functions over and over in your React applications.

useCounter showcase

Clean counter state with all the controls you need:

Loading component...

This free open source React hook simplifies numeric state operations with TypeScript support for modern JavaScript applications. Whether you're building shopping carts, game scores, or quantity selectors in your Next.js projects, this React hook keeps your counter logic clean and reusable.

Installation

npx shadcn@latest add https://www.shadcn.io/registry/use-counter.json
npx shadcn@latest add https://www.shadcn.io/registry/use-counter.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-counter.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-counter.json

Why most counter implementations suck

Look, you could keep writing useState with manual increment/decrement functions in React applications. But after the 20th shopping cart component, you'll appreciate having this handled for you.

Most developers create inline arrow functions like onClick={() => setCount(count + 1)} which cause unnecessary re-renders when passed to child components. Or they forget to memoize their counter functions and wonder why their Next.js projects feel sluggish.

The memoized callbacks in this React hook prevent unnecessary re-renders when you pass these functions to child components—something that bites people with inline arrow functions in TypeScript components. Plus you get reset functionality built-in, which you'd end up adding anyway.

It's just cleaner. Instead of five lines of boilerplate for every counter, you get one custom hook call with all the methods you need in JavaScript applications.

This free open source React hook handles the counter boilerplate while you focus on building features. Whether you're creating React applications, Next.js projects, or TypeScript codebases, this custom hook keeps your numeric state management consistent.

Features

  • Complete counter operations with increment, decrement, reset, and direct state access in React applications
  • Flexible initial values supporting any numeric starting point with optional parameters for TypeScript components
  • Optimized callbacks using React.useCallback for performance in complex component trees in Next.js projects
  • TypeScript support with comprehensive type definitions and IntelliSense integration
  • Memory efficient with memoized functions preventing unnecessary re-renders in JavaScript applications
  • Custom operations through direct setCount access for complex mathematical operations in React development
  • Free open source designed for modern React development workflows

When you'll actually use this

Real talk—this isn't for every number in your React applications. For simple display-only values, just use state. But when you need increment/decrement/reset controls that you're passing to components, this React hook shines in Next.js projects.

Perfect for:

  • Shopping carts - Quantity controls with min/max validation built with TypeScript
  • Game interfaces - Score tracking, lives, and multipliers using React patterns
  • Form inputs - Numeric steppers and quantity selectors in JavaScript applications
  • Dashboard counters - Statistics and metrics that users can adjust in React components
  • Inventory systems - Stock management with increment/decrement controls in Next.js applications
  • Pagination - Page number controls with reset to first page using TypeScript validation

API Reference

useCounter

PropTypeDefaultDescription
initialValuenumber0The starting value for the counter

Return Value

PropertyTypeDescription
countnumberCurrent counter value
increment() => voidIncreases count by 1
decrement() => voidDecreases count by 1
reset() => voidResets count to initial value
setCountReact.Dispatch<React.SetStateAction<number>>Direct state setter for custom operations

Common gotchas

Memoized callbacks don't capture scope changes: The functions are memoized for performance in React applications, but won't capture new values from your component's scope. Use setCount with updater functions if you need access to current values in TypeScript components.

Reset behavior isn't always zero: Reset goes back to the initialValue, not zero, in Next.js projects. So useCounter(5) resets to 5, not 0. If you need different reset behavior, use setCount directly.

No built-in bounds checking: The React hook doesn't enforce min/max limits in JavaScript applications. You'll need to add that logic in your component: onClick={() => count < max && increment()} or use setCount with bounds checking.

Fixed increment/decrement steps: Built-in functions always change by 1 in TypeScript projects. For custom steps, use setCount with updater functions: setCount(prev => prev + step) in React components.

Performance only matters with child props: The memoization helps when passing functions to children in Next.js applications. For simple internal use, the performance benefit is minimal.

Questions you might have