# VM (Executing JavaScript) > Stability: 2 - Stable The `vm` module provides APIs for compiling and running code within V8 Virtual Machine contexts. **The `vm` module is not a security mechanism. Do not use it to run untrusted code**. The term "sandbox" is used throughout these docs simply to refer to a separate context, and does not confer any security guarantees. JavaScript code can be compiled and run immediately or compiled, saved, and run later. A common use case is to run the code in a sandboxed environment. The sandboxed code uses a different V8 Context, meaning that it has a different global object than the rest of the code. One can provide the context by ["contextifying"][contextified] a sandbox object. The sandboxed code treats any property in the sandbox like a global variable. Any changes to global variables caused by the sandboxed code are reflected in the sandbox object. ```js const vm = require('vm'); const x = 1; const sandbox = { x: 2 }; vm.createContext(sandbox); // Contextify the sandbox. const code = 'x += 40; var y = 17;'; // `x` and `y` are global variables in the sandboxed environment. // Initially, x has the value 2 because that is the value of sandbox.x. vm.runInContext(code, sandbox); console.log(sandbox.x); // 42 console.log(sandbox.y); // 17 console.log(x); // 1; y is not defined. ``` ## Class: vm.Script Instances of the `vm.Script` class contain precompiled scripts that can be executed in specific sandboxes (or "contexts"). ### Constructor: new vm.Script(code\[, options\]) * `code` {string} The JavaScript code to compile. * `options` {Object|string} * `filename` {string} Specifies the filename used in stack traces produced by this script. **Default:** `'evalmachine.'`. * `lineOffset` {number} Specifies the line number offset that is displayed in stack traces produced by this script. **Default:** `0`. * `columnOffset` {number} Specifies the column number offset that is displayed in stack traces produced by this script. **Default:** `0`. * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or `TypedArray`, or `DataView` with V8's code cache data for the supplied source. When supplied, the `cachedDataRejected` value will be set to either `true` or `false` depending on acceptance of the data by V8. * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 will attempt to produce code cache data for `code`. Upon success, a `Buffer` with V8's code cache data will be produced and stored in the `cachedData` property of the returned `vm.Script` instance. The `cachedDataProduced` value will be set to either `true` or `false` depending on whether code cache data is produced successfully. This option is **deprecated** in favor of `script.createCachedData()`. **Default:** `false`. * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. This option is part of the experimental API for the `--experimental-modules` flag, and should not be considered stable. * `specifier` {string} specifier passed to `import()` * `module` {vm.SourceTextModule} * Returns: {Module Namespace Object|vm.SourceTextModule} Returning a `vm.SourceTextModule` is recommended in order to take advantage of error tracking, and to avoid issues with namespaces that contain `then` function exports. If `options` is a string, then it specifies the filename. Creating a new `vm.Script` object compiles `code` but does not run it. The compiled `vm.Script` can be run later multiple times. The `code` is not bound to any global object; rather, it is bound before each run, just for that run. ### script.createCachedData() * Returns: {Buffer} Creates a code cache that can be used with the Script constructor's `cachedData` option. Returns a Buffer. This method may be called at any time and any number of times. ```js const script = new vm.Script(` function add(a, b) { return a + b; } const x = add(1, 2); `); const cacheWithoutX = script.createCachedData(); script.runInThisContext(); const cacheWithX = script.createCachedData(); ``` ### script.runInContext(contextifiedSandbox\[, options\]) * `contextifiedSandbox` {Object} A [contextified][] object as returned by the `vm.createContext()` method. * `options` {Object} * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs while compiling the `code`, the line of code causing the error is attached to the stack trace. **Default:** `true`. * `timeout` {integer} Specifies the number of milliseconds to execute `code` before terminating execution. If execution is terminated, an [`Error`][] will be thrown. This value must be a strictly positive integer. * `breakOnSigint` {boolean} If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that. If execution is terminated, an [`Error`][] will be thrown. **Default:** `false`. * Returns: {any} the result of the very last statement executed in the script. Runs the compiled code contained by the `vm.Script` object within the given `contextifiedSandbox` and returns the result. Running code does not have access to local scope. The following example compiles code that increments a global variable, sets the value of another global variable, then execute the code multiple times. The globals are contained in the `sandbox` object. ```js const util = require('util'); const vm = require('vm'); const sandbox = { animal: 'cat', count: 2 }; const script = new vm.Script('count += 1; name = "kitty";'); const context = vm.createContext(sandbox); for (let i = 0; i < 10; ++i) { script.runInContext(context); } console.log(util.inspect(sandbox)); // { animal: 'cat', count: 12, name: 'kitty' } ``` Using the `timeout` or `breakOnSigint` options will result in new event loops and corresponding threads being started, which have a non-zero performance overhead. ### script.runInNewContext(\[sandbox\[, options\]\]) * `sandbox` {Object} An object that will be [contextified][]. If `undefined`, a new object will be created. * `options` {Object} * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs while compiling the `code`, the line of code causing the error is attached to the stack trace. **Default:** `true`. * `timeout` {integer} Specifies the number of milliseconds to execute `code` before terminating execution. If execution is terminated, an [`Error`][] will be thrown. This value must be a strictly positive integer. * `breakOnSigint` {boolean} If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that. If execution is terminated, an [`Error`][] will be thrown. **Default:** `false`. * `contextName` {string} Human-readable name of the newly created context. **Default:** `'VM Context i'`, where `i` is an ascending numerical index of the created context. * `contextOrigin` {string} [Origin][origin] corresponding to the newly created context for display purposes. The origin should be formatted like a URL, but with only the scheme, host, and port (if necessary), like the value of the [`url.origin`][] property of a [`URL`][] object. Most notably, this string should omit the trailing slash, as that denotes a path. **Default:** `''`. * `contextCodeGeneration` {Object} * `strings` {boolean} If set to false any calls to `eval` or function constructors (`Function`, `GeneratorFunction`, etc) will throw an `EvalError`. **Default:** `true`. * `wasm` {boolean} If set to false any attempt to compile a WebAssembly module will throw a `WebAssembly.CompileError`. **Default:** `true`. * Returns: {any} the result of the very last statement executed in the script. First contextifies the given `sandbox`, runs the compiled code contained by the `vm.Script` object within the created sandbox, and returns the result. Running code does not have access to local scope. The following example compiles code that sets a global variable, then executes the code multiple times in different contexts. The globals are set on and contained within each individual `sandbox`. ```js const util = require('util'); const vm = require('vm'); const script = new vm.Script('globalVar = "set"'); const sandboxes = [{}, {}, {}]; sandboxes.forEach((sandbox) => { script.runInNewContext(sandbox); }); console.log(util.inspect(sandboxes)); // [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] ``` ### script.runInThisContext(\[options\]) * `options` {Object} * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs while compiling the `code`, the line of code causing the error is attached to the stack trace. **Default:** `true`. * `timeout` {integer} Specifies the number of milliseconds to execute `code` before terminating execution. If execution is terminated, an [`Error`][] will be thrown. This value must be a strictly positive integer. * `breakOnSigint` {boolean} If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that. If execution is terminated, an [`Error`][] will be thrown. **Default:** `false`. * Returns: {any} the result of the very last statement executed in the script. Runs the compiled code contained by the `vm.Script` within the context of the current `global` object. Running code does not have access to local scope, but *does* have access to the current `global` object. The following example compiles code that increments a `global` variable then executes that code multiple times: ```js const vm = require('vm'); global.globalVar = 0; const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); for (let i = 0; i < 1000; ++i) { script.runInThisContext(); } console.log(globalVar); // 1000 ``` ## Class: vm.SourceTextModule > Stability: 1 - Experimental *This feature is only available with the `--experimental-vm-modules` command flag enabled.* The `vm.SourceTextModule` class provides a low-level interface for using ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script` class that closely mirrors [Source Text Module Record][]s as defined in the ECMAScript specification. Unlike `vm.Script` however, every `vm.SourceTextModule` object is bound to a context from its creation. Operations on `vm.SourceTextModule` objects are intrinsically asynchronous, in contrast with the synchronous nature of `vm.Script` objects. With the help of async functions, however, manipulating `vm.SourceTextModule` objects is fairly straightforward. Using a `vm.SourceTextModule` object requires three distinct steps: creation/parsing, linking, and evaluation. These three steps are illustrated in the following example. This implementation lies at a lower level than the [ECMAScript Module loader][]. There is also currently no way to interact with the Loader, though support is planned. ```js const vm = require('vm'); const contextifiedSandbox = vm.createContext({ secret: 42 }); (async () => { // Step 1 // // Create a Module by constructing a new `vm.SourceTextModule` object. This // parses the provided source text, throwing a `SyntaxError` if anything goes // wrong. By default, a Module is created in the top context. But here, we // specify `contextifiedSandbox` as the context this Module belongs to. // // Here, we attempt to obtain the default export from the module "foo", and // put it into local binding "secret". const bar = new vm.SourceTextModule(` import s from 'foo'; s; `, { context: contextifiedSandbox }); // Step 2 // // "Link" the imported dependencies of this Module to it. // // The provided linking callback (the "linker") accepts two arguments: the // parent module (`bar` in this case) and the string that is the specifier of // the imported module. The callback is expected to return a Module that // corresponds to the provided specifier, with certain requirements documented // in `module.link()`. // // If linking has not started for the returned Module, the same linker // callback will be called on the returned Module. // // Even top-level Modules without dependencies must be explicitly linked. The // callback provided would never be called, however. // // The link() method returns a Promise that will be resolved when all the // Promises returned by the linker resolve. // // Note: This is a contrived example in that the linker function creates a new // "foo" module every time it is called. In a full-fledged module system, a // cache would probably be used to avoid duplicated modules. async function linker(specifier, referencingModule) { if (specifier === 'foo') { return new vm.SourceTextModule(` // The "secret" variable refers to the global variable we added to // "contextifiedSandbox" when creating the context. export default secret; `, { context: referencingModule.context }); // Using `contextifiedSandbox` instead of `referencingModule.context` // here would work as well. } throw new Error(`Unable to resolve dependency: ${specifier}`); } await bar.link(linker); // Step 3 // // Evaluate the Module. The evaluate() method returns a Promise with a single // property "result" that contains the result of the very last statement // executed in the Module. In the case of `bar`, it is `s;`, which refers to // the default export of the `foo` module, the `secret` we set in the // beginning to 42. const { result } = await bar.evaluate(); console.log(result); // Prints 42. })(); ``` ### Constructor: new vm.SourceTextModule(code\[, options\]) * `code` {string} JavaScript Module code to parse * `options` * `identifier` {string} String used in stack traces. **Default:** `'vm:module(i)'` where `i` is a context-specific ascending index. * `context` {Object} The [contextified][] object as returned by the `vm.createContext()` method, to compile and evaluate this `Module` in. * `lineOffset` {integer} Specifies the line number offset that is displayed in stack traces produced by this `Module`. **Default:** `0`. * `columnOffset` {integer} Specifies the column number offset that is displayed in stack traces produced by this `Module`. **Default:** `0`. * `initializeImportMeta` {Function} Called during evaluation of this `Module` to initialize the `import.meta`. * `meta` {import.meta} * `module` {vm.SourceTextModule} * `importModuleDynamically` {Function} Called during evaluation of this module when `import()` is called. If this option is not specified, calls to `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. * `specifier` {string} specifier passed to `import()` * `module` {vm.SourceTextModule} * Returns: {Module Namespace Object|vm.SourceTextModule} Returning a `vm.SourceTextModule` is recommended in order to take advantage of error tracking, and to avoid issues with namespaces that contain `then` function exports. Creates a new ES `Module` object. Properties assigned to the `import.meta` object that are objects may allow the `Module` to access information outside the specified `context`, if the object is created in the top level context. Use `vm.runInContext()` to create objects in a specific context. ```js const vm = require('vm'); const contextifiedSandbox = vm.createContext({ secret: 42 }); (async () => { const module = new vm.SourceTextModule( 'Object.getPrototypeOf(import.meta.prop).secret = secret;', { initializeImportMeta(meta) { // Note: this object is created in the top context. As such, // Object.getPrototypeOf(import.meta.prop) points to the // Object.prototype in the top context rather than that in // the sandbox. meta.prop = {}; } }); // Since module has no dependencies, the linker function will never be called. await module.link(() => {}); await module.evaluate(); // Now, Object.prototype.secret will be equal to 42. // // To fix this problem, replace // meta.prop = {}; // above with // meta.prop = vm.runInContext('{}', contextifiedSandbox); })(); ``` ### module.dependencySpecifiers * {string[]} The specifiers of all dependencies of this module. The returned array is frozen to disallow any changes to it. Corresponds to the `[[RequestedModules]]` field of [Source Text Module Record][]s in the ECMAScript specification. ### module.error * {any} If the `module.status` is `'errored'`, this property contains the exception thrown by the module during evaluation. If the status is anything else, accessing this property will result in a thrown exception. The value `undefined` cannot be used for cases where there is not a thrown exception due to possible ambiguity with `throw undefined;`. Corresponds to the `[[EvaluationError]]` field of [Source Text Module Record][]s in the ECMAScript specification. ### module.evaluate(\[options\]) * `options` {Object} * `timeout` {integer} Specifies the number of milliseconds to evaluate before terminating execution. If execution is interrupted, an [`Error`][] will be thrown. This value must be a strictly positive integer. * `breakOnSigint` {boolean} If `true`, the execution will be terminated when `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have been attached via `process.on('SIGINT')` will be disabled during script execution, but will continue to work after that. If execution is interrupted, an [`Error`][] will be thrown. **Default:** `false`. * Returns: {Promise} Evaluate the module. This must be called after the module has been linked; otherwise it will throw an error. It could be called also when the module has already been evaluated, in which case it will do one of the following two things: * return `undefined` if the initial evaluation ended in success (`module.status` is `'evaluated'`) * rethrow the same exception the initial evaluation threw if the initial evaluation ended in an error (`module.status` is `'errored'`) This method cannot be called while the module is being evaluated (`module.status` is `'evaluating'`) to prevent infinite recursion. Corresponds to the [Evaluate() concrete method][] field of [Source Text Module Record][]s in the ECMAScript specification. ### module.link(linker) * `linker` {Function} * `specifier` {string} The specifier of the requested module: ```js import foo from 'foo'; // ^^^^^ the module specifier ``` * `referencingModule` {vm.SourceTextModule} The `Module` object `link()` is called on. * Returns: {vm.SourceTextModule|Promise} * Returns: {Promise} Link module dependencies. This method must be called before evaluation, and can only be called once per module. The function is expected to return a `Module` object or a `Promise` that eventually resolves to a `Module` object. The returned `Module` must satisfy the following two invariants: * It must belong to the same context as the parent `Module`. * Its `status` must not be `'errored'`. If the returned `Module`'s `status` is `'unlinked'`, this method will be recursively called on the returned `Module` with the same provided `linker` function. `link()` returns a `Promise` that will either get resolved when all linking instances resolve to a valid `Module`, or rejected if the linker function either throws an exception or returns an invalid `Module`. The linker function roughly corresponds to the implementation-defined [HostResolveImportedModule][] abstract operation in the ECMAScript specification, with a few key differences: * The linker function is allowed to be asynchronous while [HostResolveImportedModule][] is synchronous. The actual [HostResolveImportedModule][] implementation used during module linking is one that returns the modules linked during linking. Since at that point all modules would have been fully linked already, the [HostResolveImportedModule][] implementation is fully synchronous per specification. Corresponds to the [Link() concrete method][] field of [Source Text Module Record][]s in the ECMAScript specification. ### module.namespace * {Object} The namespace object of the module. This is only available after linking (`module.link()`) has completed. Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript specification. ### module.status * {string} The current status of the module. Will be one of: * `'unlinked'`: `module.link()` has not yet been called. * `'linking'`: `module.link()` has been called, but not all Promises returned by the linker function have been resolved yet. * `'linked'`: The module has been linked successfully, and all of its dependencies are linked, but `module.evaluate()` has not yet been called. * `'evaluating'`: The module is being evaluated through a `module.evaluate()` on itself or a parent module. * `'evaluated'`: The module has been successfully evaluated. * `'errored'`: The module has been evaluated, but an exception was thrown. Other than `'errored'`, this status string corresponds to the specification's [Source Text Module Record][]'s `[[Status]]` field. `'errored'` corresponds to `'evaluated'` in the specification, but with `[[EvaluationError]]` set to a value that is not `undefined`. ### module.identifier * {string} The identifier of the current module, as set in the constructor. ## vm.compileFunction(code\[, params\[, options\]\]) * `code` {string} The body of the function to compile. * `params` {string[]} An array of strings containing all parameters for the function. * `options` {Object} * `filename` {string} Specifies the filename used in stack traces produced by this script. **Default:** `''`. * `lineOffset` {number} Specifies the line number offset that is displayed in stack traces produced by this script. **Default:** `0`. * `columnOffset` {number} Specifies the column number offset that is displayed in stack traces produced by this script. **Default:** `0`. * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or `TypedArray`, or `DataView` with V8's code cache data for the supplied source. * `produceCachedData` {boolean} Specifies whether to produce new cache data. **Default:** `false`. * `parsingContext` {Object} The [contextified][] sandbox in which the said function should be compiled in. * `contextExtensions` {Object[]} An array containing a collection of context extensions (objects wrapping the current scope) to be applied while compiling. **Default:** `[]`. * Returns: {Function} Compiles the given code into the provided context/sandbox (if no context is supplied, the current context is used), and returns it wrapped inside a function with the given `params`. ## vm.createContext(\[sandbox\[, options\]\]) * `sandbox` {Object} * `options` {Object} * `name` {string} Human-readable name of the newly created context. **Default:** `'VM Context i'`, where `i` is an ascending numerical index of the created context. * `origin` {string} [Origin][origin] corresponding to the newly created context for display purposes. The origin should be formatted like a URL, but with only the scheme, host, and port (if necessary), like the value of the [`url.origin`][] property of a [`URL`][] object. Most notably, this string should omit the trailing slash, as that denotes a path. **Default:** `''`. * `codeGeneration` {Object} * `strings` {boolean} If set to false any calls to `eval` or function constructors (`Function`, `GeneratorFunction`, etc) will throw an `EvalError`. **Default:** `true`. * `wasm` {boolean} If set to false any attempt to compile a WebAssembly module will throw a `WebAssembly.CompileError`. **Default:** `true`. * Returns: {Object} contextified sandbox. If given a `sandbox` object, the `vm.createContext()` method will [prepare that sandbox][contextified] so that it can be used in calls to [`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such scripts, the `sandbox` object will be the global object, retaining all of its existing properties but also having the built-in objects and functions any standard [global object][] has. Outside of scripts run by the vm module, global variables will remain unchanged. ```js const util = require('util'); const vm = require('vm'); global.globalVar = 3; const sandbox = { globalVar: 1 }; vm.createContext(sandbox); vm.runInContext('globalVar *= 2;', sandbox); console.log(util.inspect(sandbox)); // { globalVar: 2 } console.log(util.inspect(globalVar)); // 3 ``` If `sandbox` is omitted (or passed explicitly as `undefined`), a new, empty [contextified][] sandbox object will be returned. The `vm.createContext()` method is primarily useful for creating a single sandbox that can be used to run multiple scripts. For instance, if emulating a web browser, the method can be used to create a single sandbox representing a window's global object, then run all `