Private State Utility
The `private` package (version 0.1.8) provides a utility for associating truly private state with any JavaScript object, predating native private class fields. It achieves this primarily through two mechanisms: `makeAccessor`, which uses closures to create a secret object accessible only via a dedicated accessor function, and `makeUniqueKey`, which generates non-enumerable, unguessable property names. A crucial update in v0.1.2 addressed memory leak issues by ensuring secret objects are directly (but securely) stored on owning objects, allowing them to be garbage collected when the owner becomes unreachable. This package, last updated significantly years ago, is largely superseded by modern JavaScript features like private class fields (`#field`) but historically offered a robust solution for encapsulation in ES5 environments.
Common errors
-
TypeError: Object.defineProperty is not a function
cause Attempting to use `makeUniqueKey()` in an environment that does not fully support ECMAScript 5's `Object.defineProperty`.fixEnsure your JavaScript environment supports ES5. If not, consider using the `makeAccessor()` approach for privacy, which relies on closure scope and is more broadly compatible. -
Cannot read properties of undefined (reading 'totallySafeProperty')
cause Trying to access a private property created with `makeAccessor()` using standard object access (e.g., `obj.totallySafeProperty`) instead of the specific accessor function.fixAlways access private state through the accessor function returned by `makeAccessor()`, like `getSecret(obj).totallySafeProperty`. -
SyntaxError: Named export 'makeAccessor' not found. The requested module 'private' does not provide an export named 'makeAccessor'
cause Incorrectly trying to import the CommonJS `private` module using ES module `import` syntax.fixChange your import statement to use CommonJS `require()`: `const { makeAccessor } = require('private');` or `const getSecret = require('private').makeAccessor();`.
Warnings
- breaking Prior to v0.1.2, this package suffered from memory leaks due to holding permanent module-local references to secret objects. This was fixed by storing secrets directly on owning objects (but securely).
- gotcha The `makeUniqueKey()` method's safety guarantees for non-discoverability and non-enumerability rely on `Object.defineProperty`. Using this in environments without a full ES5 implementation (e.g., very old browsers) may compromise privacy.
- deprecated For new JavaScript projects, native Private Class Fields (e.g., `#privateField`) introduced in ES2022 provide a standardized and often preferred way to encapsulate private state within classes, offering stronger guarantees and better tooling support.
- breaking This package is CommonJS-only and does not provide an ES module build. Attempting to use `import` syntax will result in errors.
- gotcha This package appears to be abandoned, with no significant updates or active maintenance since its early versions. It may not be compatible with very recent JavaScript runtime changes or provide security updates.
Install
-
npm install private -
yarn add private -
pnpm add private
Imports
- makeAccessor
import { makeAccessor } from 'private';const getSecret = require('private').makeAccessor(); - makeUniqueKey
import { makeUniqueKey } from 'private';const secretKey = require('private').makeUniqueKey(); - private module
import Private from 'private';
const Private = require('private');
Quickstart
const getSecret = require("private").makeAccessor();
const user = {
id: 'user-123',
name: 'Alice',
email: 'alice@example.com'
};
// Associate private data with the 'user' object
getSecret(user).passwordHash = "$2a$10$abcdefghijklmnopqrstuv.w.x.y.z";
getSecret(user).apiTokens = ['token-a', 'token-b'];
// Public properties are visible
console.log('Public user keys:', Object.keys(user)); // [ 'id', 'name', 'email' ]
console.log('Public user properties:', Object.getOwnPropertyNames(user)); // [ 'id', 'name', 'email' ]
// Private data is only accessible via the accessor function
const userData = getSecret(user);
console.log('User private data:', userData); // { passwordHash: '$2a$10$abcdefghijklmnopqrstuv.w.x.y.z', apiTokens: [ 'token-a', 'token-b' ] }
console.log('User password hash:', userData.passwordHash);