TanStack Pacer

A type-safe timing and scheduling library for debouncing, throttling, rate limiting, queuing, and batching function execution, with sync and async variants.

Library
npm
v0.22.0
767stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
71/100Good
Development Activity72
Maintenance84
Community48
Maturity40
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
90/100Excellent
Architecture88
Code Quality92
Innovation78
Learning Curve100

TanStack Pacer is a lightweight execution-control library that gives JavaScript and TypeScript applications a consistent, type-safe way to manage how often and in what order functions run. Rather than reaching for ad-hoc setTimeout wrappers or hand-rolled queue classes scattered across a codebase, teams get a single set of primitives — debounce, throttle, rate limiter, queuer, batcher, and retryer — each available in a synchronous form and a promise-aware async form with built-in error handling, retries, and abort support.

Every utility is built as a class wrapping a TanStack Store instance, so state (pending status, execution counts, queue contents) is reactive and observable rather than hidden inside closures. That same store is what powers the official React, Solid, Preact, and Angular adapter hooks (useDebouncedCallback, useThrottledValue, useQueuedState, and more), letting the same core logic drive both vanilla JS and framework-bound UI state with fine-grained re-renders.

The queuing utilities in particular go well beyond a simple FIFO: FIFO, LIFO, and priority-queue orderings are all supported, with configurable concurrency, start/stop control, and per-item expiration. The batching utilities let callers group operations by time window, item count, or a custom predicate — useful for coalescing high-frequency events (search-as-you-type, resize handlers, websocket message bursts) into fewer, cheaper downstream calls.

Built and maintained by the TanStack team behind Query, Table, and Router, Pacer follows the same conventions: framework-agnostic core, thin adapter packages per framework, full TypeScript generics for argument and return-type inference, and a devtools panel for inspecting live debouncer/throttler/queue state during development.

What You Get

  • Debounce & Throttle - synchronous and async variants with leading/trailing edge control, each backed by a reactive state object (isPending, executionCount, etc.) rather than opaque closures.
  • Rate Limiting - fixed-window and sliding-window rate limiters that cap how often a function can fire over a period, with async error/success/settled callbacks.
  • Queuing - FIFO, LIFO, and priority queues with configurable concurrency, wait times, start/stop control, and automatic expiration of stale items.
  • Batching - group calls by elapsed time, item count, or a custom condition to reduce many small operations into fewer batched executions.
  • Async Retryer - a dedicated async utility for retrying failing operations with configurable retry counts and abort support.
  • Framework Adapters - React, Solid, Preact, and Angular hooks (useDebouncedCallback, useThrottledValue, useQueuedState) built on the same core classes.
  • Devtools Panel - a dedicated @tanstack/pacer-devtools package for inspecting live debouncer/throttler/queuer state during development.
  • Full Type Safety - generics preserve the wrapped function’s argument and return types throughout every utility.

Common Use Cases

  • Search-as-you-type - debounce keystroke-driven API calls so a request only fires after the user pauses typing.
  • Scroll and resize handlers - throttle high-frequency DOM events so expensive layout or fetch logic only runs at a bounded rate.
  • Third-party API rate limiting - wrap outbound calls to a rate-limited external API in a RateLimiter to stay under quota without manual token-bucket code.
  • Background job fan-out - use a priority Queuer with a concurrency cap to process a burst of async tasks (uploads, webhook deliveries) in a controlled order.
  • Websocket/event coalescing - batch a stream of frequent websocket messages into periodic bulk UI updates instead of re-rendering on every message.
  • Flaky network calls - wrap a fetch in the async retryer to automatically retry transient failures with backoff before surfacing an error.

Under The Hood

Architecture Each utility (Debouncer, Throttler, RateLimiter, Queuer, Batcher, and their async counterparts) is a self-contained class in packages/pacer/src that wraps a Store instance from @tanstack/store as its single source of truth, with private #setState methods normalizing derived fields like status on every update and an emitChange call feeding an internal devtools event bus (event-client.ts). Public methods (maybeExecute, flush, cancel, reset) are defined as class field arrow functions so they can be destructured and passed as callbacks without losing this binding, and a plain-function wrapper (debounce, throttle, etc.) sits on top of each class for callers who don’t need direct access to the instance. Framework adapters in sibling packages (react-pacer, solid-pacer, preact-pacer, angular-pacer) subscribe to the same store to expose reactive hooks, so the core has zero framework dependency and all UI-binding logic lives at the edges.

Tech Stack The core @tanstack/pacer package is pure TypeScript with two runtime dependencies: @tanstack/store for reactive state and @tanstack/devtools-event-client for the devtools event bus. The monorepo is managed with pnpm workspaces and Nx for task orchestration/caching, built per-package with tsdown (emitting unbundled ESM and CJS output plus .d.ts files validated by publint), and tested with Vitest using fake timers to deterministically exercise time-based behavior. Framework adapter packages add their respective peer dependencies (React, Solid, Preact, Angular) on top of the same core.

Code Quality Every source file under packages/pacer/src has a matching test file under packages/pacer/tests, and the test suite (~9,700 lines) is actually larger than the source it covers (~6,500 lines), exercising basic behavior, edge cases, leading/trailing combinations, and cancellation paths with Vitest’s fake-timer APIs. The root tsconfig.json enables strict, noUncheckedIndexedAccess, noUnusedLocals, and noImplicitReturns, and CI (test:pr) runs ESLint, type-checking, sherif (monorepo dependency consistency), knip (unused exports), doc-link verification, and a full build on every pull request, with an autofix bot applying formatting and doc regeneration automatically.

What Makes It Unique Most debounce/throttle utilities on npm are single-purpose and stateless; Pacer instead treats timing control as a small family of related primitives (debounce, throttle, rate limit, queue, batch, retry) sharing one reactive-state model, so switching from a sync debouncer to an async one with retry/abort support is a drop-in change rather than a rewrite. Exposing that state through TanStack Store — the same primitive underlying TanStack Query’s cache — lets framework adapters get fine-grained reactive re-renders essentially for free, and gives every utility a built-in devtools story without extra instrumentation code.

Used by 5 apps in this directory

Python
84%
MIT

LiteLLM

AI Development · Developer Tools

58,169

Open source AI gateway and Python SDK that gives you one OpenAI-compatible interface to call 100+ LLM providers, with built-in routing, cost tracking, guardrails, and virtual keys.

View details
92
Repo Health
81
Technical
69
Dependency
Built with
Python84%
TypeScript13%
Updated today
TypeScript
88%
MIT

Mistle

AI Agents · Developer Tools

91

Self-hostable platform for running autonomous coding agents in isolated, credentialless sandboxes with brokered credentials, reusable snapshots, and event-driven triggers.

View details
70
Repo Health
76
Technical
71
Dependency
Built with
TypeScript88%
Rust11%
Updated 1 months ago
Rust
71%
Apache 2.0

Rivet

AI Agents · Developer Tools

6,116

Stateful actors as a primitive for AI agents, real-time collaboration, and durable execution — with in-memory state, WebSockets, queues, and scheduling built in.

View details
86
Repo Health
81
Technical
65
Dependency
Built with
Rust71%
TypeScript25%
Updated yesterday
Python
58%
Other

Sentry

Security · Developer Tools · Monitoring

44,739

Developer-first error tracking and performance monitoring platform with AI-powered root-cause analysis across 20+ languages and frameworks.

View details
95
Repo Health
80
Technical
69
Dependency
Built with
Python58%
TypeScript41%
Updated yesterday
Python
58%
Other

Sentry

Security · Developer Tools · Monitoring

44,739

Developer-first error tracking and performance monitoring platform with AI-powered root-cause analysis across 20+ languages and frameworks.

View details
95
Repo Health
80
Technical
69
Dependency
Built with
Python58%
TypeScript41%
Updated yesterday

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search