{"id":14851,"library":"rafu","title":"rafu","description":"rafu is a lightweight JavaScript utility that provides a `requestAnimationFrame` shim and enhanced animation scheduling capabilities. It ensures that animations run smoothly and efficiently across different browser environments by offering a robust fallback for `requestAnimationFrame` where native support might be missing or prefixed. Beyond merely polyfilling, rafu includes a `throttled` utility for synchronizing function calls with the browser's repaint cycle, which is crucial for performance-sensitive tasks like scroll handling, resize events, or continuous input processing. The package is currently at version 1.2.0, with its latest update introducing explicit cancellation methods for both direct `rafu` calls and functions created with `rafu.throttled`. Its minimal footprint and focused functionality make it a straightforward choice for projects needing basic `requestAnimationFrame` management without introducing heavy dependencies.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/danro/rafu","tags":["javascript","animation","frame","throttle"],"install":[{"cmd":"npm install rafu","lang":"bash","label":"npm"},{"cmd":"yarn add rafu","lang":"bash","label":"yarn"},{"cmd":"pnpm add rafu","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary `requestAnimationFrame` scheduling function. ESM import is preferred in modern JavaScript environments.","wrong":"const rafu = require('rafu');","symbol":"rafu","correct":"import rafu from 'rafu';"},{"note":"Used to cancel a previously scheduled `requestAnimationFrame` callback. `cancel` is a method directly on the default `rafu` export.","wrong":"import { cancel } from 'rafu'; // Incorrect if 'cancel' is a method on the default export","symbol":"rafu.cancel","correct":"import rafu from 'rafu';\nconst handle = rafu(() => {});\nrafu.cancel(handle);"},{"note":"A utility function for creating a throttled version of a callback, synchronized with `requestAnimationFrame`. `throttled` is a method directly on the default `rafu` export.","wrong":"import { throttled } from 'rafu'; // Incorrect if 'throttled' is a method on the default export","symbol":"rafu.throttled","correct":"import rafu from 'rafu';\nconst throttledScroll = rafu.throttled(() => {});"}],"quickstart":{"code":"import rafu from 'rafu';\n\nconst box = document.createElement('div');\nbox.style.width = '50px';\nbox.style.height = '50px';\nbox.style.backgroundColor = 'red';\nbox.style.position = 'absolute';\nbox.style.top = '0px';\nbox.style.left = '0px';\ndocument.body.appendChild(box);\n\nlet posX = 0;\nlet direction = 1;\n\nfunction animateBox() {\n  posX += direction * 2;\n  if (posX > window.innerWidth - 50 || posX < 0) {\n    direction *= -1;\n  }\n  box.style.left = `${posX}px`;\n  rafu(animateBox); // Schedule the next frame\n}\n\nanimateBox(); // Start the animation loop\n\n// Example of throttling a scroll event\nconst scrollHandler = () => {\n  console.log('Scroll event throttled by rafu:', window.scrollY);\n};\n\nconst throttledScrollHandler = rafu.throttled(scrollHandler);\nwindow.addEventListener('scroll', throttledScrollHandler);\n\n// To stop the animation after some time (demonstrating rafu.cancel)\nsetTimeout(() => {\n  const animationId = rafu(() => console.log('This will be cancelled'));\n  rafu.cancel(animationId);\n  console.log('Animation scheduled and then cancelled.');\n  window.removeEventListener('scroll', throttledScrollHandler);\n  console.log('Scroll handler removed.');\n}, 5000);\n","lang":"javascript","description":"Demonstrates scheduling a simple animation loop with `rafu` and throttling a scroll event handler using `rafu.throttled`."},"warnings":[{"fix":"Always test thoroughly in target browser environments. For very specific edge cases, manual feature detection might be necessary.","message":"Despite providing a `requestAnimationFrame` shim, `rafu` might still behave unexpectedly in extremely old or non-standard browser environments due to the inherent complexities of polyfilling low-level browser APIs.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always store the handle returned by `rafu()` and `rafu.throttled()` (if it returns a handle or a cancellable function), and call `rafu.cancel()` or the throttled function's `cancel()` method when the animation or effect is no longer needed.","message":"Forgetting to cancel scheduled animation frames or throttled functions can lead to memory leaks and unnecessary CPU cycles, especially if components are unmounted or removed from the DOM without proper cleanup.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure `rafu` is loaded early in your application's lifecycle, or be aware of other `requestAnimationFrame` polyfills in your dependency tree. Consider only using one source for `requestAnimationFrame` polyfilling.","message":"If another library or polyfill for `requestAnimationFrame` is loaded before `rafu`, it might overwrite or interfere with `rafu`'s shim, leading to unpredictable animation behavior or performance issues.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using the correct import syntax for your module system: `import rafu from 'rafu';` for ESM, or `const rafu = require('rafu');` for CommonJS (if supported). Double-check the package.json `exports` field if present.","cause":"Attempting to use `rafu` as a CommonJS module with `require()` when it might be designed primarily for ESM, or vice-versa, or if the import path is incorrect.","error":"TypeError: rafu is not a function"},{"fix":"Verify that `rafu` is imported as the default export: `import rafu from 'rafu';`. The `cancel` method is a property of this default export.","cause":"Calling `cancel` method when `rafu` might not be correctly imported as the default export, or `cancel` is not directly exposed as a property on the `rafu` function.","error":"TypeError: rafu.cancel is not a function"},{"fix":"Ensure `rafu` is imported as the default export (`import rafu from 'rafu';`), then access the utility as `rafu.throttled(yourFunction);`. The `throttled` method is a property of the default `rafu` export.","cause":"Attempting to access the `throttled` utility incorrectly, possibly expecting it as a named export instead of a property on the default `rafu` export.","error":"TypeError: rafu.throttled is not a function"}],"ecosystem":"npm"}