Loading...
Please waitLoading...
Please waitDetect runaway timers and detached DOM refs in development builds, warning with contextual stack traces.
pnpm dlx uselab@latest add use-memory-leak-guard
import * as React from "react"
import { useMemoryLeakGuard } from "@/hooks/use-memory-leak-guard"
export function Component() {
const retainedPanelRef = React.useRef<Element | null>(null)
useMemoryLeakGuard({
refs: [retainedPanelRef],
timerThresholdMs: 30_000,
domCheckIntervalMs: 5000,
})
React.useEffect(() => {
const id = window.setInterval(() => {
// expensive polling…
}, 2000)
return () => window.clearInterval(id)
}, [])
return (
<section>
<button
onClick={() => {
// Force a “leak”: keep a reference to a node that will be removed.
const target = document.getElementById("panel")
if (target) retainedPanelRef.current = target
}}
>
Capture panel ref
</button>
</section>
)
}| Name | Type | Description | Default Value | Optional |
|---|---|---|---|---|
options.refs | React.RefObject<Element | null>[] | Refs to watch for detached DOM nodes. | [] | Yes |
options.timerThresholdMs | number | How long a timer can live before a warning. Applies to intervals and long delays. | 60000 | Yes |
options.domCheckIntervalMs | number | How often refs are checked for detachment (ms). | 3000 | Yes |
options.flushOnUnload | boolean | Warn about active intervals during beforeunload. | false | Yes |
| Concern | Action |
|---|---|
| Runaway intervals | Logs a warning when an interval survives longer than timerThresholdMs. |
| Long-delayed timeouts | Warns when setTimeout delay exceeds timerThresholdMs. |
| Detached refs | Checks supplied refs and warns if their node is no longer inside document.body while still referenced. |
| Production builds | The hook is a no-op when process.env.NODE_ENV === "production". |
options.refs. Whenever you intentionally retain DOM nodes (portals, manual caching) remember to release them when appropriate.useMemoryLeakGuard only reports issues— it does not automatically clear timers or refs.Guard warns when an interval lives longer than 5 seconds without cleanup.
Capturing the node without releasing it simulates keeping refs to removed DOM nodes.
Recent activity