or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-filesystem.mdhelpers.mdindex.md
tile.json

tessl/npm-memfs

In-memory file-system with Node's fs API providing virtual file systems for testing, mocking, and development purposes.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/memfs@4.38.x

To install, run

npx @tessl/cli install tessl/npm-memfs@4.38.0

index.mddocs/

memfs

memfs is a comprehensive in-memory file system implementation that mimics Node.js's native fs API, enabling developers to create virtual file systems entirely in memory for testing, mocking, and development purposes. It offers full compatibility with Node.js filesystem operations while also providing browser compatibility through File System Access API adapters and OPFS (Origin Private File System) support.

Package Information

  • Package Name: memfs
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install memfs

Core Imports

import { fs, vol, memfs, Volume } from "memfs";

For individual components:

import { 
  fs,                    // Default file system instance
  vol,                   // Default volume instance
  Volume,                // Volume class
  memfs,                 // Factory function
  createFsFromVolume,    // Factory function
  DirectoryJSON,         // JSON structure type
  NestedDirectoryJSON,   // Nested JSON structure type
  IFs,                   // File system interface type
  IFsWithVolume          // File system with volume type
} from "memfs";

CommonJS:

const { fs, vol, memfs, Volume } = require("memfs");

Basic Usage

import { fs, memfs } from "memfs";

// Use the default file system
fs.writeFileSync("/hello.txt", "Hello World!");
const content = fs.readFileSync("/hello.txt", "utf8");
console.log(content); // "Hello World!"

// Create a new file system from JSON
const { fs: customFs } = memfs({
  "/app": {
    "package.json": '{"name": "my-app"}',
    "src": {
      "index.js": "console.log('Hello');"
    }
  }
});

// Read from the custom file system
const packageJson = customFs.readFileSync("/app/package.json", "utf8");
console.log(JSON.parse(packageJson).name); // "my-app"

Architecture

memfs is built around several key components:

  • Volume System: Core file system management with complete Node.js fs API compatibility
  • File System Access API: Modern browser-compatible FSA implementation for web environments
  • Bridge Adapters: Bidirectional compatibility layers between Node.js fs and FSA APIs
  • Snapshot System: File system serialization/deserialization for persistence and testing
  • Core Primitives: Low-level file system components (Node, Link, File, Superblock)
  • Utility Libraries: Tree printing, encoding helpers, and testing utilities

Capabilities

Core File System API

Complete Node.js fs API implementation with synchronous, callback, and promise-based methods. Provides drop-in replacement for Node.js fs module with full compatibility.

// Main exports
export const fs: IFs;
export const vol: Volume;
export function memfs(json?: NestedDirectoryJSON, cwd?: string): { fs: IFs; vol: Volume };
export function createFsFromVolume(vol: Volume): IFs;

// Core volume class providing complete Node.js fs API
export class Volume {
  static fromJSON(json: DirectoryJSON, cwd?: string): Volume;
  static fromNestedJSON(json: NestedDirectoryJSON, cwd?: string): Volume;
  
  // File operations (synchronous)
  readFileSync(path: PathLike, options?: any): string | Buffer;
  writeFileSync(path: PathLike, data: any, options?: any): void;
  appendFileSync(path: PathLike, data: any, options?: any): void;
  copyFileSync(src: PathLike, dest: PathLike, mode?: number): void;
  unlinkSync(path: PathLike): void;
  existsSync(path: PathLike): boolean;
  accessSync(path: PathLike, mode?: number): void;
  
  // File descriptor operations (synchronous)
  openSync(path: PathLike, flags: TFlags, mode?: TMode): number;
  closeSync(fd: number): void;
  readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number | null): number;
  writeSync(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number): number;
  
  // Directory operations (synchronous)
  mkdirSync(path: PathLike, options?: any): string | undefined;
  readdirSync(path: PathLike, options?: any): string[] | Dirent[];
  rmdirSync(path: PathLike, options?: any): void;
  rmSync(path: PathLike, options?: any): void;
  
  // File status operations (synchronous)
  statSync(path: PathLike, options?: any): Stats;
  lstatSync(path: PathLike, options?: any): Stats;
  fstatSync(fd: number, options?: any): Stats;
  
  // Link operations (synchronous)
  linkSync(existingPath: PathLike, newPath: PathLike): void;
  symlinkSync(target: PathLike, path: PathLike, type?: string): void;
  readlinkSync(path: PathLike, options?: any): string | Buffer;
  
  // Async callback API (all Node.js fs methods available)
  readFile(path: PathLike, options: any, callback: (err: Error | null, data?: any) => void): void;
  writeFile(path: PathLike, data: any, options: any, callback: (err: Error | null) => void): void;
  // ... all Node.js fs callback methods
  
  // Stream operations
  createReadStream(path: PathLike, options?: any): ReadStream;
  createWriteStream(path: PathLike, options?: any): WriteStream;
  
  // Promise API
  promises: FsPromisesApi;
  
  // Watchers
  StatWatcher: new () => StatWatcher;
  FSWatcher: new () => FSWatcher;
  ReadStream: new (...args: any[]) => ReadStream;
  WriteStream: new (...args: any[]) => WriteStream;
}

// Core interfaces
export interface IFs extends Volume {
  constants: typeof constants;
  Stats: new (...args: any[]) => Stats;
  Dirent: new (...args: any[]) => Dirent;
}

// JSON structure types
export type NestedDirectoryJSON = { [key: string]: string | Buffer | NestedDirectoryJSON | null };
export type DirectoryJSON = { [key: string]: string | Buffer | null };

// Common types used throughout the API  
export type PathLike = string | Buffer | URL;
export type TFlags = string | number;  
export type TMode = string | number;

Core File System API

Helper Classes and Utilities

File statistics, directory entries, and other utility classes available through the fs object.

// Accessible through fs.Stats constructor
interface Stats {
  isFile(): boolean;
  isDirectory(): boolean;
  isSymbolicLink(): boolean;
  size: number;
  mode: number;
  mtime: Date;
  ctime: Date;
  // ... other stat properties
}

// Accessible through fs.Dirent constructor  
interface Dirent {
  name: string;
  isFile(): boolean;
  isDirectory(): boolean;
  isSymbolicLink(): boolean;
}

// Access via fs.Stats and fs.Dirent constructors
const stats = new fs.Stats(/* ... */);
const dirent = new fs.Dirent(/* ... */);

Helper Classes and Utilities

Constants

File system constants compatible with Node.js fs.constants, accessible through the fs object.

// Access file system constants through fs object
fs.constants.F_OK;  // File existence check
fs.constants.R_OK;  // Read permission check  
fs.constants.W_OK;  // Write permission check
fs.constants.X_OK;  // Execute permission check

// Open flags
fs.constants.O_RDONLY;  // Read-only
fs.constants.O_WRONLY;  // Write-only  
fs.constants.O_RDWR;    // Read-write
fs.constants.O_CREAT;   // Create if not exists
fs.constants.O_EXCL;    // Exclusive create
fs.constants.O_TRUNC;   // Truncate to zero
fs.constants.O_APPEND;  // Append mode

// File types and permissions  
fs.constants.S_IFMT;    // File type mask
fs.constants.S_IFREG;   // Regular file
fs.constants.S_IFDIR;   // Directory
fs.constants.S_IFLNK;   // Symbolic link
// ... all standard Node.js fs constants available

Error Handling

memfs follows Node.js error handling conventions with full error type compatibility:

// Error interface matching Node.js
export interface IError extends Error {
  code?: string;
  errno?: number;
  syscall?: string;
  path?: string;
}

// Common error patterns
export interface ErrorPatterns {
  // Synchronous methods throw errors
  syncError: () => never;
  
  // Callback methods pass errors as first argument
  callbackError: (err: IError | null, result?: any) => void;
  
  // Promise methods reject with error objects
  promiseError: () => Promise<never>;
}

Error Handling Patterns:

Synchronous API:

try {
  const content = fs.readFileSync('/nonexistent.txt', 'utf8');
} catch (error) {
  console.log(error.code); // 'ENOENT'
  console.log(error.path); // '/nonexistent.txt'
  console.log(error.syscall); // 'open'
}

Callback API:

fs.readFile('/nonexistent.txt', 'utf8', (err, data) => {
  if (err) {
    console.log(err.code); // 'ENOENT'
    return;
  }
  console.log(data);
});

Promise API:

try {
  const content = await fs.promises.readFile('/nonexistent.txt', 'utf8');
} catch (error) {
  console.log(error.code); // 'ENOENT'
}

Error Code Reference:

CodeDescriptionCommon Scenarios
ENOENTFile or directory not foundReading non-existent files, accessing missing directories
EEXISTFile or directory already existsCreating files/directories that exist with exclusive flags
EISDIRExpected file but found directoryReading directory as file, writing to directory path
ENOTDIRExpected directory but found fileDirectory operations on file paths
EACCESPermission deniedAccessing files without proper permissions
EMFILEToo many open filesExceeding file descriptor limits
EBADFBad file descriptorUsing invalid or closed file descriptors
EINVALInvalid argumentInvalid parameters or options
EPERMOperation not permittedSystem-level permission restrictions