# @react-spring/rafz

> react-spring's fork of rafz one frameloop to rule them all

Latest version **10.1.2** (published 2026-06-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install @react-spring/rafz
pnpm add @react-spring/rafz
yarn add @react-spring/rafz
bun add @react-spring/rafz
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; popular repo.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 10.1.2 |
| Published | 2026-06-24 |
| First published | 2021-06-07 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 32.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 29149 |
| Author | Josh Ellis |
| Maintainers | tdfka_rick |
| Keywords | animated, animation, hooks, motion, react, react-native, spring, typescript, velocity |

## Links

- npm: https://www.npmjs.com/package/@react-spring/rafz
- Repository: https://github.com/pmndrs/react-spring
- Homepage: https://github.com/pmndrs/react-spring/tree/main/packages/rafz#readme
- Issues: https://github.com/pmndrs/react-spring/issues
- npm.io page: https://npm.io/package/@react-spring/rafz

## Alternatives

- [@luma.gl/experimental](https://npm.io/package/@luma.gl/experimental.md) — 77.1K weekly downloads
- [persona-harness](https://npm.io/package/persona-harness.md) — 4.7K weekly downloads
- [@tsparticles/effect-bubble](https://npm.io/package/@tsparticles/effect-bubble.md) — 4.6K weekly downloads
- [f3d](https://npm.io/package/f3d.md) — 730 weekly downloads
- [spark-html-motion](https://npm.io/package/spark-html-motion.md) — 298 weekly downloads

## Recent versions

- 10.1.2 (latest) — 2026-06-24
- 11.0.0-beta.0 (beta) — 2026-06-21
- 0.0.0-nightly-52cc710-20230626001840 (nightly) — 2023-06-26
- 0.0.0-65fc02cc281573bc28d90720983c8e9df9035059-20230625170003 (experimental) — 2023-06-25
- 9.4.0-alpha.0 (alpha) — 2021-10-15
- 10.1.1 — 2026-06-10
- 10.1.0 — 2026-05-22
- 10.0.4 — 2026-05-21
- 10.0.3 — 2025-09-18
- 10.0.3-beta.0 — 2025-09-16
- 10.0.2 — 2025-09-07
- 10.0.1 — 2025-05-21
- 10.0.0 — 2025-05-14
- 10.0.0-beta.0 — 2025-04-29
- 9.7.5 — 2024-10-07
- … 63 more at https://npm.io/package/@react-spring/rafz/versions

## README

# @react-spring/rafz

Coordinate `requestAnimationFrame` calls across your app and/or libraries.

- < 700 bytes min+gzip
- Timeout support
- Batching support (eg: `ReactDOM.unstable_batchedUpdates`)
- Uncaught errors are isolated
- Runs continuously (to reduce frame skips)

&nbsp;

## API

```ts
import { raf } from '@react-spring/rafz'

// Schedule an update
raf(dt => {})

// Start an update loop
raf(dt => true)

// Cancel an update
raf.cancel(fn)

// Schedule a mutation
raf.write(() => {})

// Before any updates
raf.onStart(() => {})

// Before any mutations
raf.onFrame(() => {})

// After any mutations
raf.onFinish(() => {})

// Set a timeout that runs on nearest frame
raf.setTimeout(() => {}, 1000)

// Use a polyfill
raf.use(require('@essentials/raf').raf)

// Get the current time
raf.now() // => number

// Set how you want to control raf firing
raf.frameLoop = 'demand' | 'always'
```

&nbsp;

## Notes

- Functions can only be scheduled once per queue per frame.
- Thus, trying to schedule a function twice is a no-op.
- The `update` phase is for updating JS state (eg: advancing an animation).
- The `write` phase is for updating native state (eg: mutating the DOM).
- [Reading] is allowed any time before the `write` phase.
- Writing is allowed any time after the `onFrame` phase.
- Timeout handlers run first on each frame.
- Any handler (except timeouts) can return `true` to run again next frame.
- The `raf.cancel` function only works with `raf` handlers.
- Use `raf.sync` to disable scheduling in its callback.
- Override `raf.batchedUpdates` to avoid excessive re-rendering in React.

[reading]: https://gist.github.com/paulirish/5d52fb081b3570c81e3a

&nbsp;

## `raf.throttle`

Wrap a function to limit its execution to once per frame. If called more than once
in a single frame, the last arguments are used.

```ts
let log = raf.throttle(console.log)

log(1)
log(2) // nothing logged yet

raf.onStart(() => {
  // "2" is logged by now
})

// Cancel a pending call.
log.cancel()

// Access the wrapped function.
log.handler
```

## Prior art

- [fastdom](https://github.com/wilsonpage/fastdom)
- [framesync](https://github.com/Popmotion/popmotion/tree/master/packages/framesync)

---
_Source: https://npm.io/package/@react-spring/rafz · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
