New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

fs-fixture

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-fixture

Easily create test fixtures at a temporary file-system path

latest
Source
npmnpm
Version
2.13.0
Version published
Weekly downloads
8.2K
-30.85%
Maintainers
1
Weekly downloads
 
Created
Source

fs-fixture

Simple API to create disposable test fixtures on disk. Tiny (1.1 kB gzipped) with zero dependencies!

Features

  • 📁 Create files & directories from simple objects
  • 🧹 Automatic cleanup with using keyword
  • 📝 Built-in JSON read/write support
  • 🔗 Symlink support
  • 💾 Binary file support with Buffers
  • 🎯 TypeScript-first with full type safety
  • 🔄 File methods inherit types directly from Node.js fs module
  • 🔌 Pluggable filesystem — use with @platformatic/vfs, memfs, or any fs/promises-compatible API

Installation

npm install fs-fixture

Quick start

import { createFixture } from 'fs-fixture'

// Create a temporary fixture
const fixture = await createFixture({
    'package.json': JSON.stringify({ name: 'my-app' }),
    'src/index.js': 'console.log("Hello world")'
})

// Read files
const content = await fixture.readFile('src/index.js', 'utf8')

// Cleanup when done
await fixture.rm()

Auto cleanup with using keyword

Uses TypeScript 5.2+ Explicit Resource Management for automatic cleanup:

await using fixture = await createFixture({
    'config.json': '{ "setting": true }'
})

// Fixture is automatically cleaned up when exiting scope

Already a sponsor? Join the discussion in the Development repo!

Usage

Creating fixtures

From an object:

const fixture = await createFixture({
    'package.json': '{ "name": "test" }',
    'src/index.js': 'export default () => {}',
    'src/utils': {
        'helper.js': 'export const help = () => {}'
    }
})

From a template directory:

// Copies an existing directory structure
const fixture = await createFixture('./test-templates/basic')

Empty fixture:

// Create an empty temporary directory
const fixture = await createFixture()

Working with files

File methods (readFile, writeFile, readdir) inherit their type signatures directly from Node.js fs/promises, preserving all overloads and type narrowing behavior.

Read files:

// Read as string (type: Promise<string>)
const text = await fixture.readFile('config.txt', 'utf8')

// Read as buffer (type: Promise<Buffer>)
const binary = await fixture.readFile('image.png')

Write files:

await fixture.writeFile('output.txt', 'Hello world')
await fixture.writeFile('data.bin', Buffer.from([0x89, 0x50]))

JSON operations:

// Write JSON with formatting
await fixture.writeJson('config.json', { port: 3000 })

// Read and parse JSON with type safety
type Config = { port: number }
const config = await fixture.readJson<Config>('config.json')

Working with directories

// Create directories
await fixture.mkdir('nested/folders')

// List directory contents
const files = await fixture.readdir('src')

// Copy files into fixture
await fixture.cp('/path/to/file.txt', 'copied-file.txt')

// Move or rename files
await fixture.mv('old-name.txt', 'new-name.txt')
await fixture.mv('file.txt', 'src/file.txt')

// Check if path exists
if (await fixture.exists('optional-file.txt')) {
    // ...
}

Advanced features

Dynamic content with functions:

const fixture = await createFixture({
    'target.txt': 'original file',
    'info.txt': ({ fixturePath }) => `Created at: ${fixturePath}`,
    'link.txt': ({ symlink }) => symlink('./target.txt')
})

Symlinks:

const fixture = await createFixture({
    'index.js': 'import pkg from \'pkg\'',

    // Symlink individual file or directory
    'node_modules/pkg': ({ symlink }) => symlink(process.cwd()),

    // Symlink entire directory (useful for sharing node_modules)
    node_modules: ({ symlink }) => symlink(path.resolve('node_modules'))
})

Binary files:

const fixture = await createFixture({
    'image.png': Buffer.from(imageData),
    'generated.bin': () => Buffer.from('dynamic binary content')
})

Path syntax:

const fixture = await createFixture({
    // Nested object syntax
    src: {
        utils: {
            'helper.js': 'export const help = () => {}'
        }
    },

    // Or path syntax (creates same structure)
    'src/utils/helper.js': 'export const help = () => {}'
})

Custom filesystem

Pass any fs/promises-compatible API via the fs option to use a virtual filesystem instead of disk:

import { create, MemoryProvider } from '@platformatic/vfs'
import { createFixture } from 'fs-fixture'

const fs = create(new MemoryProvider()).promises
const fixture = await createFixture({
    'package.json': JSON.stringify({ name: 'test' }),
    'src/index.js': 'export default 42'
}, { fs })

await fixture.readFile('src/index.js', 'utf8') // 'export default 42'

Works with any library that implements the fs/promises API shape, including @platformatic/vfs, the future node:vfs, and memfs.

[!NOTE] With a custom fs, files only exist in that fs instance. Use fixture.readFile() or fixture.fs to access them — fixture.path is a virtual path that doesn't exist on the real disk.

[!NOTE] Template directory sources (string paths) are not supported with custom filesystems because most virtual fs implementations lack recursive cp. Use a FileTree object instead.

API

createFixture(source?, options?)

Creates a temporary fixture directory and returns a FsFixture instance.

Parameters:

  • source (optional): String path to template directory, or FileTree object defining the structure
  • options.tempDir (optional): Custom temp directory. Defaults to os.tmpdir()
  • options.templateFilter (optional): Filter function when copying from template directory
  • options.fs (optional): Custom fs/promises-compatible API for virtual filesystem support

Returns: Promise<FsFixture>

const fixture = await createFixture()
const fixture = await createFixture({ 'file.txt': 'content' })
const fixture = await createFixture('./template-dir')
const fixture = await createFixture({}, { tempDir: './custom-temp' })

FsFixture Methods

MethodDescription
fixture.pathAbsolute path to the fixture directory
fixture.fsThe underlying fs/promises API used by the fixture
getPath(...paths)Get absolute path to file/directory in fixture
exists(path?)Check if file/directory exists
rm(path?)Delete file/directory (or entire fixture if no path)
readFile(path, encoding?)Read file as string or Buffer
writeFile(path, content)Write string or Buffer to file
readJson<T>(path)Read and parse JSON file
writeJson(path, data, space?)Write JSON with optional formatting
readdir(path, options?)List directory contents
mkdir(path)Create directory (recursive)
cp(source, dest?)Copy file/directory into fixture
mv(source, dest)Move or rename file/directory

Types

FileTree
type FileTree = {
    [path: string]: string | Buffer | FileTree | ((api: Api) => string | Buffer | Symlink)
}

type Api = {
    fixturePath: string // Fixture root path
    filePath: string // Current file path
    getPath: (...paths: string[]) => string // Get path from fixture root
    symlink: (target: string) => Symlink // Create a symlink
}
FsPromises

The subset of fs/promises methods that custom filesystem implementations must provide:

type FsPromises = {
    // Required
    readFile(path: string, options?): Promise<Buffer | string>
    writeFile(path: string, data: string | Buffer, options?): Promise<void>
    readdir(path: string, options?): Promise<string[] | Dirent[]>
    mkdir(path: string, options?): Promise<string | undefined>
    rename(oldPath: string, newPath: string): Promise<void>
    access(path: string, mode?: number): Promise<void>

    // Optional
    rm?(path: string, options?): Promise<void>
    unlink?(path: string): Promise<void>
    rmdir?(path: string): Promise<void>
    symlink?(target: string, path: string, type?: string): Promise<void>
    cp?(source: string, destination: string, options?): Promise<void>
    mkdtemp?(prefix: string): Promise<string>
}

If rm is not available, fs-fixture falls back to recursive removal using readdir({ withFileTypes }) + unlink + rmdir. If mkdtemp is not available, fixture paths are generated with a counter.

manten

Lightweight testing library for Node.js

Keywords

test

FAQs

Package last updated on 29 Mar 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts