rooks

repository·main·Indexed 25 days ago

https://github.com/imbhargav5/rooks

A collection of 147 focused, tree-shakeable, TypeScript-first React hooks for managing application state, browser APIs, events, timing, and UI behavior. It supports React and React DOM versions 18 or 19 and provides three entrypoints: stable hooks (`rooks`), experimental hooks (`rooks/experimental`), and hooks built on the JavaScript Temporal API (`rooks/temporal`).

Tokens
134K
Snippets
254
Records
493
Agent score
82%

What's inside rooks

  1. Browse the Rooks Hook Catalog

    main

    Rooks provides a wide variety of specialized React hooks categorized by their functionality. Most hooks are available via the rooks entrypoint.

    Categories:

    • DOM & Measurement: Hooks for reading element dimensions, bounding rectangles, and observing mutations or intersections (e.g., useMeasure, useBoundingclientrect, useInViewRef).
    • Media: Hooks for controlling audio and video elements, including Picture-in-Picture support (e.g., useAudio, useVideo, usePictureInPictureApi).
    • Utilities & Refs: Specialized ref management and callback utilities (e.g., useForkRef, useMergeRefs, useEventListenerRef, useFreshCallback).
    • Window & Viewport: Hooks for tracking window size and scroll position (e.g., useWindowSize, useWindowScrollPosition).
    • Media Queries: Hooks for CSS media queries and color scheme preferences (e.g., useMediaMatch, usePreferredColorScheme).
  2. Explore the Rooks Hook Catalog

    main

    Rooks provides 147 canonical hook implementations distributed across three main entrypoints. Use the entrypoint that matches your stability requirements:

    • rooks: Stable hooks (118 hooks)
    • rooks/experimental: Experimental hooks (25 hooks)
    • rooks/temporal: Temporal hooks (4 hooks)

    Common categories include Animation & Timing, Browser APIs, Development & Debugging, and Event Handling.

  3. Avoid common hydration traps

    main

    To prevent UI bugs and hydration errors, avoid these patterns:

    • Unstable Keys: Do not use browser-derived values (like window.innerWidth) as React key props.
    • Premature Assumptions: Do not assume media queries, viewport sizes, or storage values are final until the client has successfully subscribed via a hook.
    • Visual Jumps: If you need to avoid layout shifts during hydration, use CSS for the initial responsive layout and let the Rooks hook enhance the behavior after hydration.
    • Swallowing Errors: Keep permission failures and unavailable APIs visible to the user rather than silently failing.
  4. Accessibility and Server-Side Rendering with useKeys

    main

    SSR

    useKeys does nothing during server rendering.

    Accessibility Best Practices

    • Global Dialogs: Enabling preventLostKeyup affects the entire page; use it only when necessary.
    • Keyboard Layouts: Be aware that keyboard layouts vary across users.
    • Browser Priority: Browser or assistive-technology shortcuts may take priority over your implemented shortcuts.
    • User Experience: Always provide a visible action for the shortcut and avoid firing shortcuts while users are typing into input controls.
  5. Use the correct Rooks entrypoints

    main

    Rooks uses specific entrypoints to isolate dependencies and signal API stability. You should import from these designated entrypoints rather than internal source files:

    • rooks: The default entrypoint for stable hooks.
    • rooks/experimental: Use this for experimental hooks. This makes instability explicit in your import statements.
    • rooks/temporal: Use this for hooks involving the Temporal API. This keeps the BigInt requirement isolated from applications that do not need it.
  6. Handle errors with useSuspenseSessionStorageState

    main

    Since useSuspenseSessionStorageState relies on Suspense, it is a best practice in production to wrap the consuming component in an ErrorBoundary. This prevents the entire application from crashing if sessionStorage access fails (e.g., due to privacy settings or browser restrictions).

    import React, { Suspense } from "react";
    import { useSuspenseSessionStorageState } from "rooks/experimental";
    
    class ErrorBoundary extends React.Component {
      state = { hasError: false };
      static getDerivedStateFromError(error) { return { hasError: true }; }
      render() {
        if (this.state.hasError) {
          return <div><h2>Something went wrong</h2><button onClick={() => this.setState({ hasError: false })}>Try Again</button></div>;
        }
        return this.props.children;
      }
    }
    
    function TabSettings() {
      // ... useSuspenseSessionStorageState implementation
    }
    
    export default function App() {
      return (
        <ErrorBoundary>
          <Suspense fallback={<div>Loading settings...</div>}>
            <TabSettings />
          </Suspense>
        </ErrorBoundary>
      );
    }
  7. Write executable documentation examples

    main

    Examples in ts or tsx fences are typechecked against the workspace package. Follow these requirements:

    • Imports: Import from the page's real entrypoint. Include all necessary React imports and local types.
    • Scope: Use only public values and explicitly exported public types. Never instruct users to import a type unless it is explicitly exported from the package entrypoint.
    • Content: The primary example must be self-contained and render visible output (not just null).
    • Environment: Show unsupported-browser or permission fallbacks where appropriate. Keep examples static (do not use Sandpack or npm latest).
    • Non-runnable code: Use the text language tag for pseudocode or partial signatures instead of ts or tsx.
  8. Configure useTemporalAge behavior and lifecycle

    main

    Lifecycle and Updates

    • Automatic Updates: The hook automatically updates the result at the next start-of-day boundary in the specified timeZone.
    • Time Zone Changes: The hook recreates its internal store if the timeZone option changes.
    • Cleanup: The hook clears its scheduled timer during component unmount.

    Compatibility Requirements

    • Polyfill: You must install @js-temporal/polyfill to use Temporal features.
    • Runtime: Requires a runtime that supports BigInt.
    • SSR: Always render a stable null fallback during SSR to prevent hydration mismatches.
    • Accessibility: When displaying age, it is recommended to state the chosen timeZone in user-facing copy if the date might differ across regions.
  9. Migration expectations for experimental hooks

    main

    Experimental hooks may graduate to the stable rooks entrypoint, be replaced by a different design, or be removed entirely.

    When upgrading:

    • Follow the official release notes for migration paths.
    • Update both your imports and your internal adapters simultaneously.
    • Do not attempt to bypass stability by importing from undocumented paths.

    If your project requires stronger stability guarantees, use a stable alternative from the Hooks reference or implement a custom product-specific hook until the experimental API stabilizes.

  10. Choose the correct Temporal hook

    main

    Select a hook based on whether you need calendar arithmetic or instant-based durations:

    HookUse Case
    useTemporalNowWhen you need the current instant or calendar representation, updated on aligned second, minute, or day boundaries.
    useTemporalAgeWhen you need calendar years, months, and days from a date to today in a specific time zone. (Calendar arithmetic)
    useTemporalCountdownWhen you need the remaining time to a target instant and a terminal done state. (Instant-based duration)
    useTemporalElapsedWhen you need the elapsed time since a specific instant. (Instant-based duration)

    Warning: Do not substitute useTemporalAge for countdown/elapsed hooks (or vice versa) when daylight-saving or month boundaries are significant.

  11. Preview and validate documentation

    main

    Use the following commands to develop and verify documentation:

    • Start local development server: pnpm docs:dev
    • Regenerate READMEs and metadata: pnpm docs:generate or pnpm docs:generate --check (use --check to verify changes).
    • Run full documentation contract validation: pnpm docs:check (includes build and checks for schema, API parity, imports, snippets, sections, links, and formatting).
    • Run all project checks: pnpm all-checks
    • Production build only: pnpm docs:build
    pnpm docs:dev
    pnpm docs:generate
    pnpm docs:generate --check
    pnpm docs:check
    pnpm docs:build
    pnpm all-checks
  12. Use Temporal hooks

    main

    Temporal hooks are built on the JavaScript Temporal API. If your runtime does not support Temporal, you must install the @js-temporal/polyfill polyfill. These hooks require BigInt support and have specific SSR and time-zone considerations.

    pnpm add @js-temporal/polyfill
    import { useTemporalNow } from "rooks/temporal";
    
    export function Clock() {
      const now = useTemporalNow({ precision: "second" });
    
      return <time>{now?.toString() ?? "Loading time…"}</time>;
    }