The svelte-pacer adapter connects Pacer scheduling utilities to Svelte state and lifecycle management. It re-exports the core package, including utility classes, stateless functions, option types, and async retrying.
pnpm add @tanstack/svelte-pacerThe package is ESM-only and requires Node.js 20 or newer when running in Node.js.
Call factories during component initialization. Options update in a pre-render effect. Read selected state through utility.state without destructuring it outside a reactive expression. Component destruction releases subscriptions and cleans up the utility.
By default, the selected state is {}. Pass a selector to subscribe only to the fields your UI reads. The underlying store remains available for additional subscriptions.
| Utility | Instance API | State and value helpers |
|---|---|---|
| batching | createBatcher | None |
| debouncing | createDebouncer | createDebouncedSignal, createDebouncedValue |
| queuing | createQueuer | createQueuedSignal, createQueuedValue |
| rate limiting | createRateLimiter | createRateLimitedSignal, createRateLimitedValue |
| throttling | createThrottler | createThrottledSignal, createThrottledValue |
| async batching | createAsyncBatcher | None |
| async debouncing | createAsyncDebouncer | None |
| async queuing | createAsyncQueuer | createAsyncQueuedSignal |
| async rate limiting | createAsyncRateLimiter | None |
| async throttling | createAsyncThrottler | None |
This counter coalesces rapid clicks into one update after 500 ms. Flush applies the latest pending count immediately.
<script lang="ts">
import { createDebouncer } from '@tanstack/svelte-pacer'
let count = $state(0)
let debouncedCount = $state(0)
const debouncer = createDebouncer(
(value: number) => {
debouncedCount = value
},
{ wait: 500 },
(state) => ({ isPending: state.isPending }),
)
function increment() {
debouncer.maybeExecute(++count)
}
</script>
<button onclick={increment}>Increment</button>
<p>Count: {count}. Debounced: {debouncedCount}.</p>
<p>Pending: {debouncer.state.isPending}</p>
<button onclick={() => debouncer.flush()}>Flush</button>Use utility.Subscribe with a child snippet to select state without updating the utility owner's selection. Removing the component releases its subscription.
<debouncer.Subscribe selector={(state) => ({ isPending: state.isPending })}>
{#snippet children({ isPending })}
<span>Pending: {isPending}</span>
{/snippet}
</debouncer.Subscribe>Pass a plain options object, property getters, or an options factory. The adapter evaluates top-level getters, while function-valued core options remain callbacks. Options update the existing utility; pending work, counters, and the store retain their identity.
Options retain the core partial-merge behavior. Omitting a key preserves the previous setting; explicitly passing undefined clears it. key, initialState, and initialItems initialize the utility once and do not recreate it on later updates.
Wrap descendants in PacerProvider, or call providePacerOptions(() => defaults) during component initialization. Group defaults by utility, such as { debouncer: { leading: true } }. Local options take precedence.
Debouncers, throttlers, and batchers cancel pending timers by default. Queuers stop processing. Async variants also abort active work. Synchronous rate limiters need no timer cleanup.
Set onUnmount to replace the default cleanup, for example to call flush() before leaving a page. The callback receives the adapter instance and its selected state. If you replace cleanup for an async utility, call its cancellation or abort methods when needed.
Use an instance method as the event handler: maybeExecute for debouncing, throttling, and rate limiting, or addItem for batching. The instance also provides control methods and state subscriptions.
State helpers return [value, setValue, utility]; value helpers return [value, utility]. Read values by calling their accessors. Setters accept a new value or a functional update. Synchronous queue state helpers return [itemsAccessor, addItem, utility]. Async queue state helpers return [itemsAccessor, utility]; call utility.addItem() to enqueue an item. Queued value helpers return the last processed value, rather than the list of pending items.
The five async utilities preserve typed results and core error behavior. Use onSuccess, onError, and onSettled for outcomes, and asyncRetryerOptions for retry configuration. abort() is cooperative: your operation must observe the supplied abort signal. See the individual async guides for scheduling and concurrency details.
Install @tanstack/svelte-pacer-devtools and use pacerDevtoolsPlugin with the framework TanStack Devtools integration. The /production entry explicitly includes the panel in production builds.
See the generated reference for signatures, options, and return types.