Isomorphic JavaScript library for interacting with WASI modules across Node.js, browsers, and Deno
—
In-memory filesystem operations enabling WASI programs to work with files and directories without requiring host filesystem access. The MemFS (Memory Filesystem) provides a complete sandboxed filesystem that exists only in memory, perfect for secure WebAssembly execution across all JavaScript environments.
In-memory filesystem providing POSIX-like file operations.
/**
* In-memory filesystem for WASI sandboxed file operations
*/
class MemFS {
/**
* Create a new empty in-memory filesystem
*/
constructor();
/**
* Create MemFS instance from JavaScript object structure
* @param jso - JavaScript object representing filesystem structure
* @returns New MemFS instance
*/
static from_js(jso: any): MemFS;
/**
* Read directory contents
* @param path - Directory path to read
* @returns Array of directory entries with path and metadata
*/
readDir(path: string): Array<any>;
/**
* Create a directory
* @param path - Directory path to create
*/
createDir(path: string): void;
/**
* Remove a directory (must be empty)
* @param path - Directory path to remove
*/
removeDir(path: string): void;
/**
* Remove a file
* @param path - File path to remove
*/
removeFile(path: string): void;
/**
* Rename or move a file or directory
* @param path - Current path
* @param to - New path
*/
rename(path: string, to: string): void;
/**
* Get file or directory metadata
* @param path - Path to get metadata for
* @returns Object containing file metadata (size, timestamps, type)
*/
metadata(path: string): object;
/**
* Open a file for reading/writing
* @param path - File path to open
* @param options - File open options (read, write, create, etc.)
* @returns JSVirtualFile handle for file operations
*/
open(path: string, options: any): JSVirtualFile;
/**
* Free WebAssembly resources
* Call when done with the filesystem to clean up memory
*/
free(): void;
}Usage Examples:
import { MemFS } from "@wasmer/wasi";
// Create filesystem and directory structure
const fs = new MemFS();
fs.createDir("/app");
fs.createDir("/data");
fs.createDir("/tmp");
// List directory contents
const rootContents = fs.readDir("/");
console.log("Root directory:", rootContents.map(entry => entry.path));
// Work with files
const file = fs.open("/data/config.json", {
read: true,
write: true,
create: true
});
file.writeString('{"setting": "value"}');
file.seek(0);
const content = file.readString();
console.log("File content:", content);
// File operations
fs.rename("/data/config.json", "/data/settings.json");
const metadata = fs.metadata("/data/settings.json");
console.log("File size:", metadata.size);
// Cleanup
fs.removeFile("/data/settings.json");
fs.removeDir("/data");Virtual file handle providing comprehensive file I/O operations.
/**
* Virtual file handle for in-memory filesystem operations
*/
class JSVirtualFile {
/**
* Get last access time
* @returns Last access timestamp as BigInt
*/
lastAccessed(): bigint;
/**
* Get last modification time
* @returns Last modification timestamp as BigInt
*/
lastModified(): bigint;
/**
* Get file creation time
* @returns Creation timestamp as BigInt
*/
createdTime(): bigint;
/**
* Get current file size
* @returns File size in bytes as BigInt
*/
size(): bigint;
/**
* Set file size (truncate or extend)
* @param new_size - New file size in bytes
*/
setLength(new_size: bigint): void;
/**
* Read entire file contents as bytes
* @returns File contents as Uint8Array
*/
read(): Uint8Array;
/**
* Read entire file contents as string
* @returns File contents as UTF-8 string
*/
readString(): string;
/**
* Write bytes to file at current position
* @param buf - Data to write as Uint8Array
* @returns Number of bytes written
*/
write(buf: Uint8Array): number;
/**
* Write string to file at current position
* @param buf - Data to write as UTF-8 string
* @returns Number of bytes written
*/
writeString(buf: string): number;
/**
* Flush any pending writes to the filesystem
*/
flush(): void;
/**
* Seek to a specific position in the file
* @param position - Byte position to seek to
* @returns New current position
*/
seek(position: number): number;
/**
* Free WebAssembly resources
* Call when done with the file handle to clean up memory
*/
free(): void;
}File Operation Examples:
import { MemFS } from "@wasmer/wasi";
const fs = new MemFS();
// Create and write to a text file
const textFile = fs.open("/example.txt", {
read: true,
write: true,
create: true
});
textFile.writeString("Hello, WASI filesystem!\n");
textFile.writeString("This is line 2.\n");
textFile.flush();
console.log("File size:", textFile.size());
console.log("Created:", new Date(Number(textFile.createdTime())));
// Read from beginning
textFile.seek(0);
const content = textFile.readString();
console.log("File content:", content);
// Binary file operations
const binaryFile = fs.open("/data.bin", {
read: true,
write: true,
create: true
});
// Write binary data
const data = new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F]); // "Hello"
const bytesWritten = binaryFile.write(data);
console.log("Wrote", bytesWritten, "bytes");
// Read binary data
binaryFile.seek(0);
const readData = binaryFile.read();
console.log("Read bytes:", Array.from(readData).map(b => b.toString(16)));
// File manipulation
textFile.seek(0);
textFile.setLength(5n); // Truncate to 5 bytes
textFile.seek(0);
const truncated = textFile.readString();
console.log("Truncated:", truncated); // "Hello"File opening options for controlling access mode and behavior.
// File open options (passed to MemFS.open)
interface FileOpenOptions {
read?: boolean; // Allow reading from file
write?: boolean; // Allow writing to file
create?: boolean; // Create file if it doesn't exist
truncate?: boolean; // Truncate file to zero length on open
append?: boolean; // Start writing at end of file
}File Mode Examples:
// Read-only access
const readFile = fs.open("/readonly.txt", { read: true });
// Write-only with creation
const writeFile = fs.open("/output.log", {
write: true,
create: true
});
// Read-write with truncation
const rwFile = fs.open("/temp.dat", {
read: true,
write: true,
create: true,
truncate: true
});
// Append mode
const logFile = fs.open("/app.log", {
write: true,
create: true,
append: true
});The MemFS integrates seamlessly with WASI instances for program file access.
Integration Examples:
import { init, WASI, MemFS } from "@wasmer/wasi";
await init();
// Set up filesystem before WASI execution
const fs = new MemFS();
fs.createDir("/input");
fs.createDir("/output");
// Create input files
const inputFile = fs.open("/input/data.txt", {
write: true,
create: true
});
inputFile.writeString("Processing this data...\n");
// Configure WASI with custom filesystem
const wasi = new WASI({
args: ["processor", "/input/data.txt", "/output/result.txt"],
fs: fs
});
// Run WASI program
const module = await WebAssembly.compileStreaming(fetch("processor.wasm"));
await wasi.instantiate(module, {});
const exitCode = wasi.start();
// Access results through the same filesystem
if (fs.metadata("/output/result.txt")) {
const resultFile = fs.open("/output/result.txt", { read: true });
const result = resultFile.readString();
console.log("Processing result:", result);
}Common filesystem operations and patterns.
Directory Operations:
// Recursive directory creation
function createPath(fs: MemFS, path: string) {
const parts = path.split('/').filter(p => p);
let current = '';
for (const part of parts) {
current += '/' + part;
try {
fs.createDir(current);
} catch (e) {
// Directory might already exist
}
}
}
// List all files recursively
function listAllFiles(fs: MemFS, dir: string = '/'): string[] {
const files: string[] = [];
const entries = fs.readDir(dir);
for (const entry of entries) {
const fullPath = dir === '/' ? entry.path : `${dir}${entry.path}`;
if (entry.is_dir) {
files.push(...listAllFiles(fs, fullPath));
} else {
files.push(fullPath);
}
}
return files;
}Install with Tessl CLI
npx tessl i tessl/npm-wasmer--wasi