{"$schema":"https://doc-kit.nodejs.org/schemas/api-doc/1.0.0.json","id":"wasi","path":"/wasi","type":"module","module":"wasi","title":"WebAssembly System Interface (WASI)","introducedIn":"v12.16.0","sourceLink":{"path":"lib/wasi.js","url":"https://github.com/nodejs/node/blob/HEAD/lib/wasi.js"},"stability":{"index":"1","description":"Experimental"},"added":[],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"description":"<strong class=\"critical\">The `node:wasi` module does not currently provide the\ncomprehensive file system security properties provided by some WASI runtimes.\nFull support for secure file system sandboxing may or may not be implemented in\nfuture. In the mean time, do not rely on it to run untrusted code. </strong>\n\nThe WASI API provides an implementation of the [WebAssembly System Interface](https://wasi.dev/)\nspecification. WASI gives WebAssembly applications access to the underlying\noperating system via a collection of POSIX-like functions.\n\n```mjs\nimport { readFile } from 'node:fs/promises';\nimport { WASI } from 'node:wasi';\nimport { argv, env } from 'node:process';\n\nconst wasi = new WASI({\n  version: 'preview1',\n  args: argv,\n  env,\n  preopens: {\n    '/local': '/some/real/path/that/wasm/can/access',\n  },\n});\n\nconst wasm = await WebAssembly.compile(\n  await readFile(new URL('./demo.wasm', import.meta.url)),\n);\nconst instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());\n\nwasi.start(instance);\n```\n\n```cjs\nconst { readFile } = require('node:fs/promises');\nconst { WASI } = require('node:wasi');\nconst { argv, env } = require('node:process');\nconst { join } = require('node:path');\n\nconst wasi = new WASI({\n  version: 'preview1',\n  args: argv,\n  env,\n  preopens: {\n    '/local': '/some/real/path/that/wasm/can/access',\n  },\n});\n\n(async () => {\n  const wasm = await WebAssembly.compile(\n    await readFile(join(__dirname, 'demo.wasm')),\n  );\n  const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());\n\n  wasi.start(instance);\n})();\n```\n\nTo run the above example, create a new WebAssembly text format file named\n`demo.wat`:\n\n```text\n(module\n    ;; Import the required fd_write WASI function which will write the given io vectors to stdout\n    ;; The function signature for fd_write is:\n    ;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written\n    (import \"wasi_snapshot_preview1\" \"fd_write\" (func $fd_write (param i32 i32 i32 i32) (result i32)))\n\n    (memory 1)\n    (export \"memory\" (memory 0))\n\n    ;; Write 'hello world\\n' to memory at an offset of 8 bytes\n    ;; Note the trailing newline which is required for the text to appear\n    (data (i32.const 8) \"hello world\\n\")\n\n    (func $main (export \"_start\")\n        ;; Creating a new io vector within linear memory\n        (i32.store (i32.const 0) (i32.const 8))  ;; iov.iov_base - This is a pointer to the start of the 'hello world\\n' string\n        (i32.store (i32.const 4) (i32.const 12))  ;; iov.iov_len - The length of the 'hello world\\n' string\n\n        (call $fd_write\n            (i32.const 1) ;; file_descriptor - 1 for stdout\n            (i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0\n            (i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.\n            (i32.const 20) ;; nwritten - A place in memory to store the number of bytes written\n        )\n        drop ;; Discard the number of bytes written from the top of the stack\n    )\n)\n```\n\nUse [wabt](https://github.com/WebAssembly/wabt) to compile `.wat` to `.wasm`\n\n```bash\nwat2wasm demo.wat\n```","summary":"<strong class=\"critical\">The `node:wasi` module does not currently provide the comprehensive file system security properties provided by some WASI runtimes. Full support for secure file system sandboxing may or may not be implemented in future. In the mean time, do not rely on it to run untrusted code. </strong>","examples":[{"language":"mjs","displayName":null,"code":"import { readFile } from 'node:fs/promises';\nimport { WASI } from 'node:wasi';\nimport { argv, env } from 'node:process';\n\nconst wasi = new WASI({\n  version: 'preview1',\n  args: argv,\n  env,\n  preopens: {\n    '/local': '/some/real/path/that/wasm/can/access',\n  },\n});\n\nconst wasm = await WebAssembly.compile(\n  await readFile(new URL('./demo.wasm', import.meta.url)),\n);\nconst instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());\n\nwasi.start(instance);"},{"language":"cjs","displayName":null,"code":"const { readFile } = require('node:fs/promises');\nconst { WASI } = require('node:wasi');\nconst { argv, env } = require('node:process');\nconst { join } = require('node:path');\n\nconst wasi = new WASI({\n  version: 'preview1',\n  args: argv,\n  env,\n  preopens: {\n    '/local': '/some/real/path/that/wasm/can/access',\n  },\n});\n\n(async () => {\n  const wasm = await WebAssembly.compile(\n    await readFile(join(__dirname, 'demo.wasm')),\n  );\n  const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());\n\n  wasi.start(instance);\n})();"},{"language":"text","displayName":null,"code":"(module\n    ;; Import the required fd_write WASI function which will write the given io vectors to stdout\n    ;; The function signature for fd_write is:\n    ;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written\n    (import \"wasi_snapshot_preview1\" \"fd_write\" (func $fd_write (param i32 i32 i32 i32) (result i32)))\n\n    (memory 1)\n    (export \"memory\" (memory 0))\n\n    ;; Write 'hello world\\n' to memory at an offset of 8 bytes\n    ;; Note the trailing newline which is required for the text to appear\n    (data (i32.const 8) \"hello world\\n\")\n\n    (func $main (export \"_start\")\n        ;; Creating a new io vector within linear memory\n        (i32.store (i32.const 0) (i32.const 8))  ;; iov.iov_base - This is a pointer to the start of the 'hello world\\n' string\n        (i32.store (i32.const 4) (i32.const 12))  ;; iov.iov_len - The length of the 'hello world\\n' string\n\n        (call $fd_write\n            (i32.const 1) ;; file_descriptor - 1 for stdout\n            (i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0\n            (i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.\n            (i32.const 20) ;; nwritten - A place in memory to store the number of bytes written\n        )\n        drop ;; Discard the number of bytes written from the top of the stack\n    )\n)"},{"language":"bash","displayName":null,"code":"wat2wasm demo.wat"}],"children":[{"kind":"section","id":"security","name":"Security","title":"Security","scope":"module","overloadOf":null,"stability":null,"added":["v21.2.0","v20.11.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v21.2.0","v20.11.0"],"prUrl":"https://github.com/nodejs/node/pull/50396","commit":null,"description":"Clarify WASI security properties."}],"description":"WASI provides a capabilities-based model through which applications are provided\ntheir own custom `env`, `preopens`, `stdin`, `stdout`, `stderr`, and `exit`\ncapabilities.\n\n**The current Node.js threat model does not provide secure sandboxing as is\npresent in some WASI runtimes.**\n\nWhile the capability features are supported, they do not form a security model\nin Node.js. For example, the file system sandboxing can be escaped with various\ntechniques. The project is exploring whether these security guarantees could be\nadded in future.","summary":"WASI provides a capabilities-based model through which applications are provided their own custom `env`, `preopens`, `stdin`, `stdout`, `stderr`, and `exit` capabilities.","examples":[],"children":[]},{"kind":"class","id":"class-wasi","name":"WASI","title":"Class: `WASI`","scope":"module","overloadOf":null,"stability":null,"added":["v13.3.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"extends":null,"description":"The `WASI` class provides the WASI system call API and additional convenience\nmethods for working with WASI-based applications. Each `WASI` instance\nrepresents a distinct environment.","summary":"The `WASI` class provides the WASI system call API and additional convenience methods for working with WASI-based applications. Each `WASI` instance represents a distinct environment.","examples":[],"children":[{"kind":"constructor","id":"new-wasioptions","name":"WASI","title":"`new WASI([options])`","scope":"module","overloadOf":null,"stability":null,"added":["v13.3.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[{"versions":["v20.1.0"],"prUrl":"https://github.com/nodejs/node/pull/47390","commit":null,"description":"default value of returnOnExit changed to true."},{"versions":["v20.0.0"],"prUrl":"https://github.com/nodejs/node/pull/47391","commit":null,"description":"The version option is now required and has no default value."},{"versions":["v19.8.0"],"prUrl":"https://github.com/nodejs/node/pull/46469","commit":null,"description":"version field added to options."}],"signature":{"parameters":[{"name":"options","type":{"text":"Object","links":[{"name":"Object","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object","start":0,"end":6}]},"description":"","default":null,"optional":true,"rest":false,"properties":[{"name":"args","type":{"text":"Array","links":[{"name":"Array","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array","start":0,"end":5}]},"description":"An array of strings that the WebAssembly application will\nsee as command-line arguments. The first argument is the virtual path to the\nWASI command itself.","default":"[]","optional":true,"rest":false,"properties":[]},{"name":"env","type":{"text":"Object","links":[{"name":"Object","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object","start":0,"end":6}]},"description":"An object similar to `process.env` that the WebAssembly\napplication will see as its environment.","default":"{}","optional":true,"rest":false,"properties":[]},{"name":"preopens","type":{"text":"Object","links":[{"name":"Object","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object","start":0,"end":6}]},"description":"This object represents the WebAssembly application's\nlocal directory structure. The string keys of `preopens` are treated as\ndirectories within the file system. The corresponding values in `preopens`\nare the real paths to those directories on the host machine.","default":null,"optional":false,"rest":false,"properties":[]},{"name":"returnOnExit","type":{"text":"boolean","links":[{"name":"boolean","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type","start":0,"end":7}]},"description":"By default, when WASI applications call\n`__wasi_proc_exit()`  `wasi.start()` will return with the exit code\nspecified rather than terminating the process. Setting this option to\n`false` will cause the Node.js process to exit with the specified\nexit code instead.","default":"true","optional":true,"rest":false,"properties":[]},{"name":"stdin","type":{"text":"integer","links":[{"name":"integer","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type","start":0,"end":7}]},"description":"The file descriptor used as standard input in the\nWebAssembly application.","default":"0","optional":true,"rest":false,"properties":[]},{"name":"stdout","type":{"text":"integer","links":[{"name":"integer","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type","start":0,"end":7}]},"description":"The file descriptor used as standard output in the\nWebAssembly application.","default":"1","optional":true,"rest":false,"properties":[]},{"name":"stderr","type":{"text":"integer","links":[{"name":"integer","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type","start":0,"end":7}]},"description":"The file descriptor used as standard error in the\nWebAssembly application.","default":"2","optional":true,"rest":false,"properties":[]},{"name":"version","type":{"text":"string","links":[{"name":"string","href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type","start":0,"end":6}]},"description":"The version of WASI requested. Currently the only\nsupported versions are `unstable` and `preview1`. This option is\nmandatory.","default":null,"optional":false,"rest":false,"properties":[]}]}],"returns":null},"description":"","summary":"","examples":[],"children":[]},{"kind":"method","id":"wasigetimportobject","name":"getImportObject","title":"`wasi.getImportObject()`","scope":"module","overloadOf":null,"stability":null,"added":["v19.8.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"signature":{"parameters":[],"returns":null},"description":"Return an import object that can be passed to `WebAssembly.instantiate()` if\nno other WASM imports are needed beyond those provided by WASI.\n\nIf version `unstable` was passed into the constructor it will return:\n\n```json\n{ wasi_unstable: wasi.wasiImport }\n```\n\nIf version `preview1` was passed into the constructor it will return:\n\n```json\n{ wasi_snapshot_preview1: wasi.wasiImport }\n```","summary":"Return an import object that can be passed to `WebAssembly.instantiate()` if no other WASM imports are needed beyond those provided by WASI.","examples":[{"language":"json","displayName":null,"code":"{ wasi_unstable: wasi.wasiImport }"},{"language":"json","displayName":null,"code":"{ wasi_snapshot_preview1: wasi.wasiImport }"}],"children":[]},{"kind":"method","id":"wasistartinstance","name":"start","title":"`wasi.start(instance)`","scope":"module","overloadOf":null,"stability":null,"added":["v13.3.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"signature":{"parameters":[{"name":"instance","type":{"text":"WebAssembly.Instance","links":[{"name":"WebAssembly.Instance","href":"WebAssembly.html#class-webassemblyinstance","start":0,"end":20}]},"description":"","default":null,"optional":false,"rest":false,"properties":[]}],"returns":null},"description":"Attempt to begin execution of `instance` as a WASI command by invoking its\n`_start()` export. If `instance` does not contain a `_start()` export, or if\n`instance` contains an `_initialize()` export, then an exception is thrown.\n\n`start()` requires that `instance` exports a [`WebAssembly.Memory`](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Memory) named\n`memory`. If `instance` does not have a `memory` export an exception is thrown.\n\nIf `start()` is called more than once, an exception is thrown.","summary":"Attempt to begin execution of `instance` as a WASI command by invoking its `_start()` export. If `instance` does not contain a `_start()` export, or if `instance` contains an `_initialize()` export, then an exception is thrown.","examples":[],"children":[]},{"kind":"method","id":"wasiinitializeinstance","name":"initialize","title":"`wasi.initialize(instance)`","scope":"module","overloadOf":null,"stability":null,"added":["v14.6.0","v12.19.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"signature":{"parameters":[{"name":"instance","type":{"text":"WebAssembly.Instance","links":[{"name":"WebAssembly.Instance","href":"WebAssembly.html#class-webassemblyinstance","start":0,"end":20}]},"description":"","default":null,"optional":false,"rest":false,"properties":[]}],"returns":null},"description":"Attempt to initialize `instance` as a WASI reactor by invoking its\n`_initialize()` export, if it is present. If `instance` contains a `_start()`\nexport, then an exception is thrown.\n\n`initialize()` requires that `instance` exports a [`WebAssembly.Memory`](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Memory) named\n`memory`. If `instance` does not have a `memory` export an exception is thrown.\n\nIf `initialize()` is called more than once, an exception is thrown.","summary":"Attempt to initialize `instance` as a WASI reactor by invoking its `_initialize()` export, if it is present. If `instance` contains a `_start()` export, then an exception is thrown.","examples":[],"children":[]},{"kind":"method","id":"wasifinalizebindingsinstance-options","name":"finalizeBindings","title":"`wasi.finalizeBindings(instance[, options])`","scope":"module","overloadOf":null,"stability":null,"added":["v24.4.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"signature":{"parameters":[{"name":"instance","type":{"text":"WebAssembly.Instance","links":[{"name":"WebAssembly.Instance","href":"WebAssembly.html#class-webassemblyinstance","start":0,"end":20}]},"description":"","default":null,"optional":false,"rest":false,"properties":[]},{"name":"options","type":{"text":"Object","links":[{"name":"Object","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object","start":0,"end":6}]},"description":"","default":null,"optional":true,"rest":false,"properties":[{"name":"memory","type":{"text":"WebAssembly.Memory","links":[{"name":"WebAssembly.Memory","href":"WebAssembly.html#class-webassemblymemory","start":0,"end":18}]},"description":"","default":"instance.exports.memory","optional":true,"rest":false,"properties":[]}]}],"returns":null},"description":"Set up WASI host bindings to `instance` without calling `initialize()`\nor `start()`. This method is useful when the WASI module is instantiated in\nchild threads for sharing the memory across threads.\n\n`finalizeBindings()` requires that either `instance` exports a\n[`WebAssembly.Memory`](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Memory) named `memory` or user specify a\n[`WebAssembly.Memory`](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Memory) object in `options.memory`. If the `memory` is invalid\nan exception is thrown.\n\n`start()` and `initialize()` will call `finalizeBindings()` internally.\nIf `finalizeBindings()` is called more than once, an exception is thrown.","summary":"Set up WASI host bindings to `instance` without calling `initialize()` or `start()`. This method is useful when the WASI module is instantiated in child threads for sharing the memory across threads.","examples":[],"children":[]},{"kind":"property","id":"wasiwasiimport","name":"wasiImport","title":"`wasi.wasiImport`","scope":"module","overloadOf":null,"stability":null,"added":["v13.3.0","v12.16.0"],"deprecated":[],"removed":[],"napiVersion":[],"changes":[],"type":{"text":"Object","links":[{"name":"Object","href":"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object","start":0,"end":6}]},"default":null,"description":"`wasiImport` is an object that implements the WASI system call API. This object\nshould be passed as the `wasi_snapshot_preview1` import during the instantiation\nof a [`WebAssembly.Instance`](https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/JavaScript_interface/Instance).","summary":"`wasiImport` is an object that implements the WASI system call API. This object should be passed as the `wasi_snapshot_preview1` import during the instantiation of a `WebAssembly.Instance`.","examples":[],"children":[]}]}]}