CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-memfs

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

core-filesystem.mddocs/

Core File System API

Complete Node.js fs API implementation providing drop-in replacement functionality with synchronous, callback, and promise-based methods for all file system operations.

Core Imports

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

Capabilities

Volume Class

Core file system volume that implements the complete Node.js fs API.

/**
 * Core file system volume class implementing complete Node.js fs API
 */
export class Volume {
  // Static factory methods for creating volumes from JSON
  static fromJSON(json: DirectoryJSON, cwd?: string): Volume;
  static fromNestedJSON(json: NestedDirectoryJSON, cwd?: string): Volume;
  
  // Promise-based API matching Node.js fs.promises
  promises: FsPromisesApi;
  
  // Stream constructors
  ReadStream: new (...args: any[]) => ReadStream; 
  WriteStream: new (...args: any[]) => WriteStream;
  StatWatcher: new () => StatWatcher;
  FSWatcher: new () => FSWatcher;
}

Usage Examples:

import { Volume, memfs } from "memfs";

// Create volume from nested JSON structure
const vol = Volume.fromNestedJSON({
  '/app': {
    'package.json': '{"name": "my-app"}',
    'src': {
      'index.js': 'console.log("Hello");'
    }
  }
});

// Create file system from JSON with current working directory
const { fs, vol: customVol } = memfs({
  'config.json': '{"port": 3000}',
  'logs': null  // empty directory
}, '/app');

// Use volume directly
vol.writeFileSync('/test.txt', 'Hello World!');
const content = vol.readFileSync('/test.txt', 'utf8');

Synchronous File Operations

All Node.js synchronous file operations with identical signatures and behavior.

// File reading and writing
readFileSync(path: PathLike, options?: { encoding?: BufferEncoding | null; flag?: string } | BufferEncoding | null): string | Buffer;
writeFileSync(path: PathLike, data: string | Buffer | Uint8Array, options?: WriteFileOptions): void;
appendFileSync(path: PathLike, data: string | Buffer | Uint8Array, options?: WriteFileOptions): void;

// File metadata and operations
accessSync(path: PathLike, mode?: number): void;
existsSync(path: PathLike): boolean;
copyFileSync(src: PathLike, dest: PathLike, mode?: number): void;
unlinkSync(path: PathLike): void;
truncateSync(path: PathLike, len?: number): void;

// File descriptor operations
openSync(path: PathLike, flags: string | number, mode?: string | number): number;
closeSync(fd: number): void;
readSync(fd: number, buffer: Buffer | Uint8Array, offset: number, length: number, position: number | null): number;
writeSync(fd: number, buffer: Buffer | Uint8Array, offset?: number, length?: number, position?: number): number;
writeSync(fd: number, string: string, position?: number, encoding?: BufferEncoding): number;
ftruncateSync(fd: number, len?: number): void;
fdatasyncSync(fd: number): void;
fsyncSync(fd: number): void;

// File statistics
statSync(path: PathLike, options?: StatOptions): Stats;
lstatSync(path: PathLike, options?: StatOptions): Stats;
fstatSync(fd: number, options?: StatOptions): Stats;
statfsSync(path: PathLike, options?: StatfsOptions): StatFs;

// File permissions and ownership
chmodSync(path: PathLike, mode: string | number): void;
fchmodSync(fd: number, mode: string | number): void;
lchmodSync(path: PathLike, mode: string | number): void;
chownSync(path: PathLike, uid: number, gid: number): void;
fchownSync(fd: number, uid: number, gid: number): void;
lchownSync(path: PathLike, uid: number, gid: number): void;

// File timestamps
utimesSync(path: PathLike, atime: string | number | Date, mtime: string | number | Date): void;
futimesSync(fd: number, atime: string | number | Date, mtime: string | number | Date): void;
lutimesSync(path: PathLike, atime: string | number | Date, mtime: string | number | Date): void;

// Path resolution
realpathSync(path: PathLike, options?: { encoding?: BufferEncoding | null }): string;
realpathSync.native(path: PathLike, options?: { encoding?: BufferEncoding | null }): string;

Usage Examples:

import { fs } from "memfs";

// File operations
fs.writeFileSync('/data.txt', 'Hello World!');
const content = fs.readFileSync('/data.txt', 'utf8');
fs.appendFileSync('/data.txt', '\nNew line');

// File descriptor operations
const fd = fs.openSync('/data.txt', 'r');
const buffer = Buffer.alloc(1024);
const bytesRead = fs.readSync(fd, buffer, 0, 1024, 0);
fs.closeSync(fd);

// File metadata
const stats = fs.statSync('/data.txt');
console.log(stats.size, stats.isFile(), stats.mtime);

// File permissions
fs.chmodSync('/data.txt', 0o644);
fs.utimesSync('/data.txt', new Date(), new Date());

Synchronous Directory Operations

Complete directory management with creation, reading, and removal capabilities.

// Directory creation and removal
mkdirSync(path: PathLike, options?: MakeDirectoryOptions | string | number): void;
mkdtempSync(prefix: string, options?: { encoding?: BufferEncoding | null }): string;
rmdirSync(path: PathLike, options?: RmDirOptions): void;
rmSync(path: PathLike, options?: RmOptions): void;
cpSync(src: PathLike, dest: PathLike, options?: CpOptions): void;

// Directory reading
readdirSync(path: PathLike, options?: { encoding?: BufferEncoding | null; withFileTypes?: false }): string[];
readdirSync(path: PathLike, options: { encoding: "buffer"; withFileTypes?: false } | "buffer"): Buffer[];
readdirSync(path: PathLike, options?: { encoding?: BufferEncoding | null; withFileTypes: true }): Dirent[];
opendirSync(path: PathLike, options?: OpenDirOptions): Dir;

// Link operations
linkSync(existingPath: PathLike, newPath: PathLike): void;
symlinkSync(target: PathLike, path: PathLike, type?: string): void;
readlinkSync(path: PathLike, options?: { encoding?: BufferEncoding | null }): string;

// Glob operations
globSync(pattern: string, options?: GlobOptions): string[];

Usage Examples:

import { fs } from "memfs";

// Directory operations
fs.mkdirSync('/app/src', { recursive: true });
fs.mkdtempSync('/tmp/temp-');

// Directory reading
const files = fs.readdirSync('/app');
const entries = fs.readdirSync('/app', { withFileTypes: true });
entries.forEach(entry => {
  if (entry.isDirectory()) {
    console.log(`Directory: ${entry.name}`);
  } else {
    console.log(`File: ${entry.name}`);
  }
});

// Link operations
fs.linkSync('/app/src/index.js', '/app/main.js');
fs.symlinkSync('../config.json', '/app/src/config.json');
const target = fs.readlinkSync('/app/src/config.json');

// Glob pattern matching
const jsFiles = fs.globSync('/app/**/*.js');

Callback File System API

Complete callback-based API matching Node.js fs module exactly, with error-first callback pattern.

// File operations with callbacks
readFile(path: PathLike, options?: { encoding?: BufferEncoding | null; flag?: string } | BufferEncoding | null, callback?: (err: NodeJS.ErrnoException | null, data: string | Buffer) => void): void;
writeFile(path: PathLike, data: string | Buffer | Uint8Array, options: WriteFileOptions, callback: NoParamCallback): void;
writeFile(path: PathLike, data: string | Buffer | Uint8Array, callback: NoParamCallback): void;
appendFile(path: PathLike, data: string | Buffer | Uint8Array, options: WriteFileOptions, callback: NoParamCallback): void;
appendFile(path: PathLike, data: string | Buffer | Uint8Array, callback: NoParamCallback): void;

// Directory operations with callbacks
mkdir(path: PathLike, options: MakeDirectoryOptions, callback: (err: NodeJS.ErrnoException | null, path?: string) => void): void;
mkdir(path: PathLike, callback: NoParamCallback): void;
readdir(path: PathLike, options: { encoding: BufferEncoding | null; withFileTypes: false } | BufferEncoding | null, callback: (err: NodeJS.ErrnoException | null, files: string[]) => void): void;
readdir(path: PathLike, options: { encoding: "buffer"; withFileTypes: false } | "buffer", callback: (err: NodeJS.ErrnoException | null, files: Buffer[]) => void): void;
readdir(path: PathLike, options: { encoding?: BufferEncoding | null; withFileTypes: true }, callback: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void): void;
readdir(path: PathLike, callback: (err: NodeJS.ErrnoException | null, files: string[]) => void): void;

// Stream creation
createReadStream(path: PathLike, options?: string | { flags?: string; encoding?: BufferEncoding; fd?: number; mode?: number; autoClose?: boolean; start?: number; end?: number; highWaterMark?: number }): ReadStream;
createWriteStream(path: PathLike, options?: string | { flags?: string; encoding?: BufferEncoding; fd?: number; mode?: number; autoClose?: boolean; start?: number; highWaterMark?: number }): WriteStream;

// File watching
watch(filename: PathLike, options?: { encoding?: BufferEncoding | null; persistent?: boolean; recursive?: boolean } | BufferEncoding | null, listener?: (eventType: string, filename: string | Buffer) => void): FSWatcher;
watchFile(filename: PathLike, options: { bigint?: boolean; persistent?: boolean; interval?: number }, listener: (curr: Stats, prev: Stats) => void): StatWatcher;
watchFile(filename: PathLike, listener: (curr: Stats, prev: Stats) => void): StatWatcher;
unwatchFile(filename: PathLike, listener?: (curr: Stats, prev: Stats) => void): void;

Usage Examples:

import { fs } from "memfs";

// Callback-based file operations
fs.readFile('/data.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

fs.writeFile('/output.txt', 'Hello', (err) => {
  if (err) throw err;
  console.log('File written!');
});

// Callback-based directory operations
fs.mkdir('/app/logs', { recursive: true }, (err) => {
  if (err) throw err;
  
  fs.readdir('/app', (err, files) => {
    if (err) throw err;
    console.log('Files:', files);
  });
});

// Stream operations
const readStream = fs.createReadStream('/large-file.txt');
const writeStream = fs.createWriteStream('/copy.txt');
readStream.pipe(writeStream);

// File watching
const watcher = fs.watch('/app', { recursive: true }, (eventType, filename) => {
  console.log(`File ${filename} ${eventType}`);
});

Promise File System API

Modern promise-based API available via fs.promises with async/await support.

/**
 * Promise-based file system API accessed via fs.promises
 */
export interface FsPromisesApi {
  // File operations
  readFile(path: PathLike, options?: { encoding?: BufferEncoding | null; flag?: string } | BufferEncoding | null): Promise<string | Buffer>;
  writeFile(path: PathLike, data: string | Buffer | Uint8Array, options?: WriteFileOptions): Promise<void>;
  appendFile(path: PathLike, data: string | Buffer | Uint8Array, options?: WriteFileOptions): Promise<void>;
  access(path: PathLike, mode?: number): Promise<void>;
  copyFile(src: PathLike, dest: PathLike, mode?: number): Promise<void>;
  unlink(path: PathLike): Promise<void>;
  truncate(path: PathLike, len?: number): Promise<void>;

  // File handle operations
  open(path: PathLike, flags: string | number, mode?: string | number): Promise<FileHandle>;
  
  // Directory operations
  mkdir(path: PathLike, options?: MakeDirectoryOptions): Promise<string | void>;
  readdir(path: PathLike, options?: { encoding?: BufferEncoding | null; withFileTypes?: false }): Promise<string[]>;
  readdir(path: PathLike, options: { encoding: "buffer"; withFileTypes?: false } | "buffer"): Promise<Buffer[]>;
  readdir(path: PathLike, options: { encoding?: BufferEncoding | null; withFileTypes: true }): Promise<Dirent[]>;
  rmdir(path: PathLike, options?: RmDirOptions): Promise<void>;
  rm(path: PathLike, options?: RmOptions): Promise<void>;
  
  // File statistics
  stat(path: PathLike, options?: StatOptions): Promise<Stats>;
  lstat(path: PathLike, options?: StatOptions): Promise<Stats>;
  
  // File watching
  watch(filename: PathLike, options?: { encoding?: BufferEncoding | null; persistent?: boolean; recursive?: boolean }): AsyncIterableIterator<{ eventType: string; filename: string | Buffer }>;
  
  // File handle constructor
  FileHandle: new (...args: any[]) => FileHandle;
}

Usage Examples:

import { fs } from "memfs";

async function example() {
  try {
    // File operations with async/await
    await fs.promises.writeFile('/data.txt', 'Hello World!');
    const content = await fs.promises.readFile('/data.txt', 'utf8');
    console.log(content);

    // Directory operations
    await fs.promises.mkdir('/app/logs', { recursive: true });
    const files = await fs.promises.readdir('/app');
    
    // File handle operations
    const fileHandle = await fs.promises.open('/data.txt', 'r');
    const buffer = Buffer.alloc(1024);
    const result = await fileHandle.read(buffer, 0, 1024, 0);
    await fileHandle.close();
    
    // File statistics
    const stats = await fs.promises.stat('/data.txt');
    console.log('File size:', stats.size);
    
  } catch (error) {
    console.error('Error:', error);
  }
}

// File watching with async iteration
async function watchFiles() {
  try {
    for await (const { eventType, filename } of fs.promises.watch('/app')) {
      console.log(`${filename} ${eventType}`);
    }
  } catch (error) {
    console.error('Watch error:', error);
  }
}

JSON Structure Types

Type definitions for creating file systems from JSON representations.

/**
 * Nested directory structure allowing directories and files
 */
export type NestedDirectoryJSON<T = string | Buffer> = {
  [key: string]: T | NestedDirectoryJSON<T> | null;
};

/**
 * Flat directory structure with absolute paths
 */
export type DirectoryJSON<T = string | Buffer> = {
  [key: string]: T | null;
};

/**
 * Utility function to flatten nested JSON to flat structure
 */
export function flattenJSON<T>(
  nestedJSON: NestedDirectoryJSON<T>,
  prefix?: string
): DirectoryJSON<T>;

Usage Examples:

import { memfs, Volume, NestedDirectoryJSON } from "memfs";

// Nested JSON structure
const nestedStructure: NestedDirectoryJSON = {
  '/app': {
    'package.json': JSON.stringify({ name: 'my-app', version: '1.0.0' }),
    'src': {
      'index.js': 'console.log("Hello World!");',
      'utils': {
        'helper.js': 'module.exports = { format: s => s.trim() };'
      }
    },
    'tests': {
      'index.test.js': 'test("should work", () => { expect(true).toBe(true); });'
    },
    'logs': null,  // empty directory
    'README.md': '# My App\n\nA simple application.'
  }
};

// Create file system from nested structure
const { fs } = memfs(nestedStructure);

// Flat JSON structure (direct path mapping)
const flatStructure = {
  '/app/package.json': '{"name": "my-app"}',
  '/app/src/index.js': 'console.log("Hello");',
  '/app/logs': null
};

const vol = Volume.fromJSON(flatStructure);

Type Definitions

// Path-like types
export type PathLike = string | Buffer | URL;

// Option interfaces
export interface WriteFileOptions {
  encoding?: BufferEncoding | null;
  mode?: string | number;
  flag?: string;
}

export interface StatOptions {
  bigint?: boolean;
}

export interface StatfsOptions {
  bigint?: boolean;
}

export interface MakeDirectoryOptions {
  recursive?: boolean;
  mode?: string | number;
}

export interface RmDirOptions {
  maxRetries?: number;
  recursive?: boolean;
  retryDelay?: number;
}

export interface RmOptions {
  force?: boolean;
  maxRetries?: number;
  recursive?: boolean;
  retryDelay?: number;
}

export interface CpOptions {
  dereference?: boolean;
  errorOnExist?: boolean;
  filter?: (source: string, destination: string) => boolean | Promise<boolean>;
  force?: boolean;
  preserveTimestamps?: boolean;
  recursive?: boolean;
}

export interface OpenDirOptions {
  encoding?: BufferEncoding;
  bufferSize?: number;
}

export interface GlobOptions {
  cwd?: string;
  root?: string;
  dot?: boolean;
  nomount?: boolean;
  mark?: boolean;
  nosort?: boolean;
  stat?: boolean;
  silent?: boolean;
  strict?: boolean;
  cache?: { [path: string]: any };
  statCache?: { [path: string]: Stats | false };
  symlinks?: { [path: string]: boolean };
  nounique?: boolean;
  nonull?: boolean;
  debug?: boolean;
  nobrace?: boolean;
  noglobstar?: boolean;
  noext?: boolean;
  nocase?: boolean;
  matchBase?: boolean;
  nodir?: boolean;
  ignore?: string | string[];
  follow?: boolean;
  realpath?: boolean;
  nonegate?: boolean;
  nocomment?: boolean;
  minimatch?: any;
  flipNegate?: boolean;
}

// Callback types
export type NoParamCallback = (err: NodeJS.ErrnoException | null) => void;

docs

core-filesystem.md

helpers.md

index.md

tile.json