Registry / crm-productivity / gc-hook

gc-hook

JSON →
library0.4.1jsnpmunverified

gc-hook is a utility library that simplifies the use of JavaScript's `FinalizationRegistry` for managing object lifecycle and reacting to garbage collection. The current stable version is 0.4.1, with the last publish being a year ago, suggesting a mature but not rapidly evolving codebase. It differentiates itself by addressing common pitfalls associated with `FinalizationRegistry`, such as preventing accidental leaks of the registered reference, allowing flexible proxy overrides, and providing mechanisms for explicit deregistration via held references or tokens. Its primary goal is to abstract away the complex specifics of `FinalizationRegistry`, enabling developers to focus on application logic rather than the intricacies of memory management. It works in both CommonJS and ES module environments, offering broad compatibility.

npm install gc-hook
INSTALL
IMPORT
SIG · GC-HOOK
G
gc-hook
crm-productivityjavascriptv0.4.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

create
import { create } from 'gc-hook';
const create = require('gc-hook').create;
Used for registering an object with a cleanup callback, returning a proxy by default. Both ESM and CommonJS imports are supported.
drop
import { drop } from 'gc-hook';
const drop = require('gc-hook').drop;
Used for explicitly unregistering a held reference from the GC hook.

Demonstrates how to use `create` to register an object with a garbage collection callback, showing basic lifecycle management and explicit cleanup.

import { create, drop } from 'gc-hook'; // Keep a count of all passed references created here let references = 0; // Notify how many references are still around once collected const onGarbageCollected = myUtility => { console.log(--references, 'references still used'); }; const createUtility = options => { const myUtility = { ...options, do: 'something' }; console.log(++references, 'references provided'); // Return a proxy to avoid holding directly myUtility, // while keeping the utility in memory until such proxy // is not needed, used, or referenced anymore. return create(myUtility, onGarbageCollected); }; // As a module consumer: let util = createUtility({ some: 'thing' }); console.log('Utility created:', util); // Do something amazing with the util... // Simulate releasing the utility after some time setTimeout(() => { // Clear the utility or don't reference it anymore anywhere util = null; console.log('Utility reference cleared. Awaiting GC...'); // Once the GC kicks in, the module.js will log how many // utilities are still around and never collected. // Note: GC is non-deterministic, so the log might not appear immediately. }, 100);
Debug
Known issues
gotchaGarbage collection (GC) and thus `FinalizationRegistry` callbacks are inherently non-deterministic. Cleanup functions are not guaranteed to execute immediately, or even at all, if the process terminates before GC runs. Do not rely on them for essential program logic or timely resource release.
fix
Design your application with robust fallback mechanisms for resource cleanup, such as explicit `dispose()` methods or other lifecycle hooks, rather than solely depending on GC for critical tasks.
affects: >=0.1.0
gotchaBy default, `create` returns a `Proxy` around the registered object. This proxy is what prevents the original object from being prematurely garbage collected. Developers should be aware of proxy behavior, especially when relying on strict object identity checks or direct property enumeration, which might behave differently than with plain objects.
fix
If direct access to the original object or a custom wrapper is needed without proxy behavior, use the `return` option in `create(value, callback, { return: customWrapper })`.
affects: >=0.1.0
gotchaA common footgun with `FinalizationRegistry` is inadvertently creating a strong reference to the target object within the cleanup callback itself. While `gc-hook` is designed to mitigate this, developers must ensure their `onGarbageCollected` function does not capture or re-establish a strong reference to the object it is intended to finalize, which would prevent its garbage collection.
fix
Carefully review cleanup callbacks to ensure they only use the provided `heldValue` argument and do not close over or retain strong references to the original `target` or its related state after it's meant to be unreachable. `gc-hook`'s design helps, but developer vigilance is still required.
affects: >=0.1.0
Errors
Common errors & fixes
My cleanup callback function never runs, or runs much later than expected.
Garbage collection is non-deterministic and controlled by the JavaScript engine. It is not guaranteed to run at any specific time or even at all before a process exits. This is a fundamental characteristic of `FinalizationRegistry`.
fix
Understand and communicate that `FinalizationRegistry` is for 'best-effort' cleanup, not guaranteed resource release. For critical resources, implement explicit `close()` or `dispose()` methods. To observe GC activity more reliably in development, try running with `--expose-gc` flag in Node.js and manually calling `global.gc()`.
My object is still in memory even after I set all its references to `null`.
There might still be a strong reference to the object preventing it from being garbage collected. This could be an accidental closure, a global reference, or an issue within the `onGarbageCollected` callback itself if it retains a strong reference to the `heldValue` or `target`.
fix
Thoroughly inspect all code paths for strong references. Use a memory profiler (e.g., Chrome DevTools heap snapshot) to identify what is still holding onto the object. Ensure the `onGarbageCollected` callback does not create new strong references to the object it's meant to clean up. If using `gc-hook/track`, remember it uses `console.debug`, which might have its own retention behavior in some environments.
I'm trying to access a property on the object returned by `create` but it behaves unexpectedly or causes errors related to Proxies.
By default, `gc-hook`'s `create` function returns a `Proxy` around the target object to prevent strong references. Direct interaction with this proxy might behave differently from the raw object, especially with operations that assume direct object identity or prototype chain traversal.
fix
If you need to interact with the raw object or a specific wrapper, consider using the `return` option in `create`. For example, `create(ref, onGC, { return: ref })` would return the `ref` itself, though this negates the strong reference protection `gc-hook` provides and should only be done if you are sure about managing references externally.
Upgrade
Version history
0.4.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
42 hits · last 30 days
node
36
OpenAI (training)
1
Resources
gc-hook — npm install gc-hook · libregistry