react-freeze

Suspends re-renders of hidden React component subtrees while preserving their state and native views.

Library
npm
v1.0.4
1,654stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
44/100Fair
Development Activity16
Maintenance20
Community44
Maturity56
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
64/100Good
Architecture68
Code Quality78
Innovation85
Learning Curve25

react-freeze is a small React library from Software Mansion that lets you pause rendering for parts of a component tree using the Suspense mechanism introduced in React 17. Instead of unmounting components you want to hide — such as screens sitting underneath the active one in a navigation stack — you wrap them in a <Freeze> component that throws a never-resolving thenable to suspend their render pass while keeping their DOM nodes or native views, state, and scroll position fully intact.

It was built to solve a specific problem in React Navigation for React Native: stack-based navigators keep previous screens mounted so back-navigation is instant, but those hidden screens still re-render on every state or store update even though nothing is visible. react-freeze integrates with react-native-screens to skip that wasted work, and it works equally well as a standalone primitive in web React apps for tab panels, off-screen carousel items, or any subtree that shouldn’t re-render while hidden.

What You Get

  • A single <Freeze> component with a freeze boolean prop and optional placeholder fallback
  • State and native view preservation for frozen subtrees — no unmount, no lost scroll position or input state
  • Drop-in integration with react-native-screens and React Navigation via enableFreeze(true)
  • A zero-runtime-dependency implementation (only a peer dependency on React 17+) built on a single throwing Suspender component

Common Use Cases

  • Freezing inactive stack screens in React Navigation so they stop re-rendering while off-screen
  • Pausing hidden tab or carousel panels in web apps that shouldn’t process store updates until visible
  • Preventing background list sections or off-viewport content from re-rendering on every state change
  • Keeping scroll position, form input, and loaded images unchanged when a view is temporarily hidden

Under The Hood

Architecture The entire implementation lives in a single ~30-line file (src/index.tsx) that exports one component, Freeze. It composes a Suspense boundary around an internal Suspender component; when the freeze prop is true, Suspender throws a module-level, never-resolving thenable (infiniteThenable), which trips React’s Suspense mechanism and holds the subtree’s commit — rendering the placeholder fallback — without ever unmounting the underlying tree. There is no additional layering, state, or dependency injection: the whole behavior is one conditional throw wrapped in two nested components, which keeps the surface area (and the number of things that can go wrong) deliberately minimal.

Tech Stack Written in TypeScript against a peer dependency on React 17+, with a parallel react-native entry point that points directly at the TypeScript source so React Native’s Metro bundler consumes it unbundled. It’s built with microbundle-crl into modern ESM and CJS bundles for regular React consumers, tested with the Create React App test runner (react-scripts test) on top of Jest and react-test-renderer, type-checked with tsc --noEmit, and linted with ESLint (typescript-eslint plus eslint-config-standard-react) and Prettier. It has no runtime dependencies beyond React itself.

Code Quality A dedicated test file exercises the full freeze/defrost lifecycle — initial render, suspending on freeze, state changes not propagating while frozen, and state changes replaying correctly on defrost — using act() and react-test-renderer, which is thorough coverage for a library this size. Props are typed via explicit TypeScript interfaces, and CI (GitHub Actions) runs unit tests, lint, type-checking, and the build on every push and pull request to main, so regressions in any of those dimensions are caught automatically.

API Design The public API is a single component with two props — a required freeze boolean and an optional placeholder node — so adopting it requires no configuration beyond wrapping existing JSX. Naming is self-descriptive, and the README pairs the quick-start snippet with an extensive FAQ that walks through edge cases (what happens to state updates while frozen, how scroll position and native views survive, what can break if you freeze the wrong subtree), which is unusually thorough documentation for a library this small.

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