WASI Preview2 shim for JS environments
npm install @bytecodealliance/preview2-shimWASI Preview2 implementations for Node.js & browsers.
Node.js support is fully tested and conformant against the Wasmtime test suite.
Browser support is considered experimental, and not currently suitable for production applications.
An default instantiation object can be used via the WASIShim class in @bytecodealliance/preview2-shim/instantiation:
``typescript
import { WASIShim } from '@bytecodealliance/preview2-shim/instantiation';
import type {
VersionedWASIImportObject,
WASIImportObject,
} from '@bytecodealliance/preview2-shim/instantiation';
const shim = new WASIShim();
const unversioned: WASIImportObject = shim.getImportObject();
// console.log('unversioned', unversioned);
unversioned satisfies WASIImportObject;
unversioned satisfies VersionedWASIImportObject<''>;
const versioned: VersionedWASIImportObject<'0.2.3'> = shim.getImportObject({
asVersion: '0.2.3',
});
//console.log('versioned', versioned);
versioned satisfies VersionedWASIImportObject<'0.2.3'>;
`
The import object generated by getImportObject can be easily used in instantiate() callsjco transpile
produced by [][jco] (with --instantiation=async):
`js
import { WASIShim } from '@bytecodealliance/preview2-shim/instantiation';
// The code below assumes that you have output your transpiled WebAssembly component to dist/transpiled
import { instantiate } from './dist/transpiled/component.js';
const loader = async (path: string) => {
const buf = await readFile(./dist/transpiled/${path});
return await WebAssembly.compile(buf.buffer as ArrayBuffer);
};
const component = await instantiate(loader, new WASIShim().getImportObject());
// TODO: Code that uses your component's exports goes here.
`
By default, the preview2-shim provides full access to the host filesystem, environment variables,
and network - matching the default behavior of Node.js libraries. However, you can configure
sandboxing to restrict what guests can access.
The WASIShim class accepts a sandbox configuration option to control access:
`js
import { WASIShim } from '@bytecodealliance/preview2-shim/instantiation';
// Fully sandboxed - no filesystem, network, or env access
const sandboxedShim = new WASIShim({
sandbox: {
preopens: {}, // No filesystem access
env: {}, // No environment variables
args: ['arg1'], // Custom arguments
enableNetwork: false, // Disable network access
}
});
// Limited filesystem access - map virtual paths to host paths
const limitedShim = new WASIShim({
sandbox: {
preopens: {
'/data': '/tmp/guest-data', // Guest sees /data, maps to /tmp/guest-data
'/config': '/etc/app' // Guest sees /config, maps to /etc/app
},
env: { 'ENV1': '42' }, // Only expose specific env vars
}
});
const component = await instantiate(loader, sandboxedShim.getImportObject());
`
- By default (when no options are passed), the shim is providing full access to match typical
Node.js library behavior.
- Each WASIShim instance has its own isolated preopens, environment variables, and arguments._setPreopens
Multiple instances with different configurations will not affect each other.
- The direct preopen functions (, _clearPreopens, etc.) modify global state andWASIShim
affect all components not using with explicit configuration. For isolation, preferWASIShim
using with the sandbox option containing preopens and env.sandbox.enableNetwork: false`, all socket and HTTP operations will throw "access-denied" errors.
- When
[jco]: https://www.npmjs.com/package/@bytecodealliance/jco
This project is licensed under the Apache 2.0 license with the LLVM exception.
See LICENSE for more details.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be licensed as above, without any additional terms or conditions.