Gathering detailed insights and metrics for private
Gathering detailed insights and metrics for private
Gathering detailed insights and metrics for private
Gathering detailed insights and metrics for private
@babel/plugin-transform-private-methods
This plugin transforms private class methods
@babel/plugin-proposal-private-methods
This plugin transforms private class methods
@babel/plugin-proposal-private-property-in-object
This plugin transforms checks for a private property in an object
@babel/plugin-transform-private-property-in-object
This plugin transforms checks for a private property in an object
Utility for associating truly private state with any JavaScript object
npm install private
Typescript
Module System
Min. Node Version
Node Version
NPM Version
JavaScript (100%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
55 Stars
50 Commits
6 Forks
2 Watchers
17 Branches
3 Contributors
Updated on Mar 02, 2025
Latest Version
0.1.8
Package Id
private@0.1.8
Size
5.12 kB
NPM Version
5.4.2
Node Version
8.7.0
Published on
Oct 13, 2017
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
1
A general-purpose utility for associating truly private state with any JavaScript object.
From NPM:
npm install private
From GitHub:
cd path/to/node_modules
git clone git://github.com/benjamn/private.git
cd private
npm install .
Get or create a secret object associated with any (non-frozen) object:
1var getSecret = require("private").makeAccessor();
2var obj = Object.create(null); // any kind of object works
3getSecret(obj).totallySafeProperty = "p455w0rd";
4
5console.log(Object.keys(obj)); // []
6console.log(Object.getOwnPropertyNames(obj)); // []
7console.log(getSecret(obj)); // { totallySafeProperty: "p455w0rd" }
Now, only code that has a reference to both getSecret
and obj
can possibly access .totallySafeProperty
.
Importantly, no global references to the secret object are retained by the private
package, so as soon as obj
gets garbage collected, the secret will be reclaimed as well. In other words, you don't have to worry about memory leaks.
Create a unique property name that cannot be enumerated or guessed:
1var secretKey = require("private").makeUniqueKey();
2var obj = Object.create(null); // any kind of object works
3
4Object.defineProperty(obj, secretKey, {
5 value: { totallySafeProperty: "p455w0rd" },
6 enumerable: false // optional; non-enumerability is the default
7});
8
9Object.defineProperty(obj, "nonEnumerableProperty", {
10 value: "anyone can guess my name",
11 enumerable: false
12});
13
14console.log(obj[secretKey].totallySafeProperty); // p455w0rd
15console.log(obj.nonEnumerableProperty); // "anyone can guess my name"
16console.log(Object.keys(obj)); // []
17console.log(Object.getOwnPropertyNames(obj)); // ["nonEnumerableProperty"]
18
19for (var key in obj) {
20 console.log(key); // never called
21}
Because these keys are non-enumerable, you can't discover them using a for
-in
loop. Because secretKey
is a long string of random characters, you would have a lot of trouble guessing it. And because the private
module wraps Object.getOwnPropertyNames
to exclude the keys it generates, you can't even use that interface to discover it.
Unless you have access to the value of the secretKey
property name, there is no way to access the value associated with it. So your only responsibility as secret-keeper is to avoid handing out the value of secretKey
to untrusted code.
Think of this style as a home-grown version of the first style. Note, however, that it requires a full implementation of ES5's Object.defineProperty
method in order to make any safety guarantees, whereas the first example will provide safety even in environments that do not support Object.defineProperty
.
In JavaScript, the only data that are truly private are local variables whose values do not leak from the scope in which they were defined.
This notion of closure privacy is powerful, and it readily provides some of the benefits of traditional data privacy, a la Java or C++:
1function MyClass(secret) { 2 this.increment = function() { 3 return ++secret; 4 }; 5} 6 7var mc = new MyClass(3); 8console.log(mc.increment()); // 4
You can learn something about secret
by calling .increment()
, and you
can increase its value by one as many times as you like, but you can never
decrease its value, because it is completely inaccessible except through
the .increment
method. And if the .increment
method were not
available, it would be as if no secret
variable had ever been declared,
as far as you could tell.
This style breaks down as soon as you want to inherit methods from the prototype of a class:
1function MyClass(secret) { 2 this.secret = secret; 3} 4 5MyClass.prototype.increment = function() { 6 return ++this.secret; 7};
The only way to communicate between the MyClass
constructor and the
.increment
method in this example is to manipulate shared properties of
this
. Unfortunately this.secret
is now exposed to unlicensed
modification:
1var mc = new MyClass(6); 2console.log(mc.increment()); // 7 3mc.secret -= Infinity; 4console.log(mc.increment()); // -Infinity 5mc.secret = "Go home JavaScript, you're drunk."; 6mc.increment(); // NaN
Another problem with closure privacy is that it only lends itself to
per-instance privacy, whereas the private
keyword in most
object-oriented languages indicates that the data member in question is
visible to all instances of the same class.
Suppose you have a Node
class with a notion of parents and children:
1function Node() { 2 var parent; 3 var children = []; 4 5 this.getParent = function() { 6 return parent; 7 }; 8 9 this.appendChild = function(child) { 10 children.push(child); 11 child.parent = this; // Can this be made to work? 12 }; 13}
The desire here is to allow other Node
objects to manipulate the value
returned by .getParent()
, but otherwise disallow any modification of the
parent
variable. You could expose a .setParent
function, but then
anyone could call it, and you might as well give up on the getter/setter
pattern.
This module solves both of these problems.
Let's revisit the Node
example from above:
1var p = require("private").makeAccessor(); 2 3function Node() { 4 var privates = p(this); 5 var children = []; 6 7 this.getParent = function() { 8 return privates.parent; 9 }; 10 11 this.appendChild = function(child) { 12 children.push(child); 13 var cp = p(child); 14 if (cp.parent) 15 cp.parent.removeChild(child); 16 cp.parent = this; 17 return child; 18 }; 19}
Now, in order to access the private data of a Node
object, you need to
have access to the unique p
function that is being used here. This is
already an improvement over the previous example, because it allows
restricted access by other Node
instances, but can it help with the
Node.prototype
problem too?
Yes it can!
1var p = require("private").makeAccessor(); 2 3function Node() { 4 p(this).children = []; 5} 6 7var Np = Node.prototype; 8 9Np.getParent = function() { 10 return p(this).parent; 11}; 12 13Np.appendChild = function(child) { 14 p(this).children.push(child); 15 var cp = p(child); 16 if (cp.parent) 17 cp.parent.removeChild(child); 18 cp.parent = this; 19 return child; 20};
Because p
is in scope not only within the Node
constructor but also
within Node
methods, we can finally avoid redefining methods every time
the Node
constructor is called.
Now, you might be wondering how you can restrict access to p
so that no
untrusted code is able to call it. The answer is to use your favorite
module pattern, be it CommonJS, AMD define
, or even the old
Immediately-Invoked Function Expression:
1var Node = (function() { 2 var p = require("private").makeAccessor(); 3 4 function Node() { 5 p(this).children = []; 6 } 7 8 var Np = Node.prototype; 9 10 Np.getParent = function() { 11 return p(this).parent; 12 }; 13 14 Np.appendChild = function(child) { 15 p(this).children.push(child); 16 var cp = p(child); 17 if (cp.parent) 18 cp.parent.removeChild(child); 19 cp.parent = this; 20 return child; 21 }; 22 23 return Node; 24}()); 25 26var parent = new Node; 27var child = new Node; 28parent.appendChild(child); 29assert.strictEqual(child.getParent(), parent);
Because this version of p
never leaks from the enclosing function scope,
only Node
objects have access to it.
So, you see, the claim I made at the beginning of this README remains true:
In JavaScript, the only data that are truly private are local variables whose values do not leak from the scope in which they were defined.
It just so happens that closure privacy is sufficient to implement a privacy model similar to that provided by other languages.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
5 existing vulnerabilities detected
Details
Reason
Found 2/25 approved changesets -- score normalized to 0
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More