Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does --frozen-intrinsics flag do in node.js?

Tags:

node.js

The documentation for --frozen-intrinsics says:

Only the root context is supported. There is no guarantee that globalThis.Array is indeed the default intrinsic reference. Code may break under this flag

I couldn't understand this. Can someone help me understand this in simple words with an example?

Background: I was checking nicolo-ribaudo/jest-light-runner where there is a mention of --frozen-intrinsics.

like image 767
Wajahath Avatar asked Nov 28 '25 13:11

Wajahath


1 Answers

When you use --frozen-intrinsics, all the built-in JavaScript objects and functions are recursively frozen, except for globalThis.

If you run node --frozen-intrinsics, you can check it:

> Object.isFrozen(Array)
true
> Object.isFrozen(Array.prototype)
true
> Object.isFrozen(globalThis);
false
> Array.isArray = () => true; Array.isArray(2); // you cannot modify built-in properties, this will not return true
false
> globalThis.foo = 3; foo; // you can still define new globals
3
> globalThis.Array = 4; Array; // However, you can also replace existing globals
4

This prevents your code from accidentally modifying globals, so I recommended it in jest-light-runner to prevent tests from accidentally influencing each other (since it doesn't isolate test files like Jest's default runner does). Note that you still have a communication channel by attaching new properties to the global object, so it's not an isolation mechanism.

Now, lets take a look at the docs you quoted.

Only the root context is supported.

In Node.js, you can create multiple "global contexts" using the vm built-in module. --frozen-intrinsics does not affect those contexts, so if you run node with --frozen-intrinsics:

> Object.isFrozen(Array)
true
> Object.isFrozen(require("vm").runInNewContext("Array"))
false

There is no guarantee that globalThis.Array is indeed the default intrinsic reference.

As mentioned earlier, globalThis.Array could still be replaced. However, if you have a "safe reference" to an object (either using syntax, or by storing the original Array global in a local variable), you can be sure that it's not modified:

let OriginalArray = Array;

require("untrusted-module");

globalThis.Array; // this might have been replaces
[].push; // this is still the original one
OriginalArray.isArray; // this is still the original one

Code may break under this flag

If code needs to modify built-ins, it would obviously stop working. For example, you cannot use polyfills that modify the global objects.

like image 90
Nicolò Avatar answered Dec 01 '25 12:12

Nicolò



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!