{"id":14940,"library":"sticky-module","title":"Sticky Module Singleton Utility","description":"sticky-module is a specialized JavaScript utility designed to guarantee that a given module is instantiated and evaluated only once, even across multiple imports or different bundling contexts within an application. It achieves this by storing and retrieving module instances using a unique, Symbol-based key, effectively creating an application-wide singleton for that module. This mechanism is particularly useful for libraries or components that require strict single-instance behavior to maintain consistent state or prevent redundant setup in complex module graphs, micro-frontends, or scenarios with multiple bundler outputs. The current stable version is 0.1.1. Its release cadence is likely slow, focusing on stability given its niche purpose. A key differentiator is its Symbol-based internal storage, which offers a robust and collision-resistant approach to global module caching compared to string-based keys.","status":"active","version":"0.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/WebReflection/sticky-module","tags":["javascript","sticky","module"],"install":[{"cmd":"npm install sticky-module","lang":"bash","label":"npm"},{"cmd":"yarn add sticky-module","lang":"bash","label":"yarn"},{"cmd":"pnpm add sticky-module","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"sticky-module is an ESM-first package and exposes a default export. CommonJS require() will likely fail or return an unexpected object.","wrong":"const stickyModule = require('sticky-module');","symbol":"stickyModule","correct":"import stickyModule from 'sticky-module';"},{"note":"The function returns a two-element array: the stored module object and a boolean indicating if it was already known. Destructure accordingly.","wrong":"let { config, known } = stickyModule('my-config', { config: {} });","symbol":"Module interface","correct":"let [{ config }, known] = stickyModule('my-config', { config: {} });"}],"quickstart":{"code":"import stickyModule from 'sticky-module';\n\nconsole.log('--- First attempt to get module ---');\nlet [{a, b}, known] = stickyModule('@custom/my-singleton', {\n  a: Math.random(),\n  b: 'initial value'\n});\n\nconsole.log(`Was module known? ${known}`);    // Expected: false\nconsole.log(`Module values: a=${a}, b='${b}'`); // Shows initial random 'a' and 'b'\n\n// Simulate a delay or another part of the application importing it later\nsetTimeout(() => {\n  console.log('\\n--- Second attempt to get module (after delay) ---');\n  let [{a: a2, b: b2}, known2] = stickyModule('@custom/my-singleton', {\n    a: Math.random(), // This value will be ignored as module is already stored\n    b: 'new value, ignored' // This value will also be ignored\n  });\n\n  console.log(`Was module known? ${known2}`);    // Expected: true\n  console.log(`Module values: a=${a2}, b='${b2}'`); // Shows the *same* initial random 'a' and 'b'\n\n  // Verify they are the same instance/values\n  console.log(`Are 'a' and 'a2' the same? ${a === a2}`); // Expected: true\n  console.log(`Are 'b' and 'b2' the same? ${b === b2}`); // Expected: true\n}, 100);\n","lang":"javascript","description":"Demonstrates how sticky-module ensures a module is initialized only once, returning the original instance on subsequent calls."},"warnings":[{"fix":"Be mindful of what data you store in 'sticky' modules. Ensure large objects are managed appropriately or consider if this pattern is suitable for your use case if memory pressure is a concern.","message":"The package description explicitly calls itself a 'leaky utility'. This implies that once a module is stored, it will persist in memory for the lifetime of the JavaScript realm and is not automatically garbage collected unless the application explicitly manages its removal (which sticky-module itself does not provide an API for). This is intentional for its singleton purpose but can be a concern for long-running applications or if modules store large objects.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Do not assume global singleton behavior across distinct JavaScript realms. If cross-realm singletons are required, an alternative inter-realm communication or shared memory solution is needed.","message":"The module uses a Symbol-based key for internal storage, which makes it effective for singleton enforcement within a single JavaScript realm (e.g., a single browser window, a Node.js process). However, this mechanism does not extend across different realms like iframes, Web Workers (without SharedWorker), or separate Node.js child processes, where each would have its own independent module storage.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Pin to exact versions or use care when upgrading, especially when a 1.0.0 release is made available. Review release notes thoroughly for any breaking changes.","message":"Given the current version is 0.1.1, any future major release (e.g., 1.0.0) is very likely to introduce breaking changes without a deprecation cycle. APIs might change significantly, or internal mechanisms could be altered.","severity":"breaking","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 `import stickyModule from 'sticky-module';` in an ESM context. If using CommonJS, check your build tools for proper ESM-to-CJS interop or consider using dynamic import `import('sticky-module').then(m => m.default)`.","cause":"This typically occurs when attempting to import 'sticky-module' using CommonJS `require()` syntax in a project that expects ESM, or if transpilation is misconfigured, leading to the default export not being correctly resolved.","error":"TypeError: stickyModule is not a function"},{"fix":"Use the correct default import syntax: `import stickyModule from 'sticky-module';`. If in TypeScript, ensure `\"esModuleInterop\": true` and `\"allowSyntheticDefaultImports\": true` are set in your `tsconfig.json`.","cause":"This error can occur if you're trying to destructure a named export when `sticky-module` only provides a default export, or if your TypeScript configuration (e.g., `esModuleInterop`) is not correctly set up for handling default ESM imports.","error":"Module 'sticky-module' has no default export."}],"ecosystem":"npm"}