Skip to content

brrock/tiny-virtfs

Repository files navigation

tiny-virtfs

npm version npm downloads NPM Unpacked Size

A minimal virtual filesystem for test suites. 306 LOC, zero runtime dependencies.

Installation

# whatever pkg manager you want
npm i tiny-virtfs

Usage

import VirtFS from "tiny-virtfs";

// Create a virtual filesystem
const fs = new VirtFS();

// Basic operations
fs.write("/src/index.ts", 'export const hello = "world"');
fs.write("/src/utils/helper.ts", "export const help = () => {}");
fs.mkdir("/dist");

// Read files
const content = fs.readString("/src/index.ts"); // "export const hello = "world""

// Check existence
fs.exists("/src/index.ts"); // true
fs.isFile("/src"); // false
fs.isDir("/src"); // true

// List directory
fs.list("/src"); // ['index.ts', 'utils']

// Copy/move
fs.copy("/src/index.ts", "/backup/index.ts");
fs.move("/src/utils", "/src/lib");

// Remove
fs.remove("/backup");

// Convert to plain object (great for snapshots)
fs.toTree();
// { src: { 'index.ts': 'export const hello = "world"', lib: { ... } } }

// Create from tree
const fs2 = VirtFS.fromTree({
  "package.json": '{"name": "my-app"}',
  src: {
    "index.ts": 'console.log("hello")',
  },
});

// Dump to real filesystem (useful for test fixtures)
await fs.dumpToDisk("./test-output");

// Load from real filesystem
const fs3 = await VirtFS.fromDisk("./my-project");

API

File Operations

  • write(path, content) - Write a file (creates parent dirs automatically)
  • read(path) - Read file content (returns string | Buffer | undefined)
  • readString(path) - Read as string (converts Buffer to UTF-8)

Directory Operations

  • mkdir(path) - Create directory (and all parents)
  • list(path) - List directory contents
  • remove(path) - Remove file or directory

Queries

  • exists(path) - Check if path exists
  • isFile(path) - Check if path is a file
  • isDir(path) - Check if path is a directory

Copy/Move

  • copy(src, dest) - Copy file or directory
  • move(src, dest) - Move file or directory

Tree Operations

  • toTree() - Export to plain object (great for snapshots)
  • VirtFS.fromTree(obj) - Create from plain object

Real Filesystem (Node.js)

  • dumpToDisk(path) - Async: Write virtual FS to real directory
  • dumpToDiskSync(path) - Sync: Write virtual FS to real directory
  • VirtFS.fromDisk(path) - Async: Load real directory into virtual FS

Mock Node.js fs Module

  • mockNodeFS() - Intercept supported node:fs and node:fs/promises calls, returns restore function
  • Sync: readFileSync, writeFileSync, existsSync, statSync, lstatSync, mkdirSync, readdirSync, rmSync, unlinkSync, rmdirSync, cpSync, renameSync, accessSync
  • Async/promises: readFile, writeFile, mkdir, readdir, stat, lstat, rm, unlink, rmdir, cp, rename, access

Benchmarks

Run with bun benchmark.ts on this machine. Higher is better.

Operation tiny-virtfs memfs memory-fs tiny vs memfs tiny vs memory-fs
write 6243.66k ops/s 137.17k ops/s 1172.22k ops/s 45.5x 5.3x
read 4682.56k ops/s 101.87k ops/s 842.03k ops/s 46.0x 5.6x
exists 1882.00k ops/s 147.27k ops/s 812.28k ops/s 12.8x 2.3x
mkdir 1582.89k ops/s 80.73k ops/s 1424.45k ops/s 19.6x 1.1x
deep write 1277.19k ops/s 43.16k ops/s 471.70k ops/s 29.6x 2.7x
many files 63.02k ops/s 1.91k ops/s 18.33k ops/s 33.0x 3.4x

Utility

  • clear() - Remove all files

Use Cases

Perfect for:

  • Testing file transformations (compilers, bundlers, generators)
  • Mocking filesystem operations
  • Creating test fixtures
  • Snapshot testing file structures

Example: Testing Functions That Use node:fs

import VirtFS from "tiny-virtfs";

// Your function that internally uses node:fs
function readConfig(path: string) {
  const fs = require("node:fs");
  return JSON.parse(fs.readFileSync(path, "utf-8"));
}

describe("readConfig", () => {
  it("parses config file", () => {
    const vfs = new VirtFS();
    vfs.write("/config.json", '{"port": 3000}');

    // Redirect all node:fs calls to virtual filesystem
    const restore = vfs.mockNodeFS();

    const config = readConfig("/config.json");
    expect(config.port).toBe(3000);

    // Restore real node:fs
    restore();
  });
});

Example: Testing shadcn Components

import VirtFS from "tiny-virtfs";

describe("component generator", () => {
  it("generates a button component", async () => {
    const fs = new VirtFS();

    // Simulate shadcn output
    fs.write(
      "/components/ui/button.tsx",
      `
      export function Button({ children }) {
        return <button>{children}</button>;
      }
    `,
    );

    // Write to real filesystem for manual inspection
    await fs.dumpToDisk("./test-output");

    // Or snapshot the tree
    expect(fs.toTree()).toMatchSnapshot();
  });
});

License

MIT

About

10kb virtual fs for test suites or whatever. zero deps. 316 LOCs. dirt simple.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors