Quick Start
import { createFixture } from 'fs-fixture'
// From object — keys are paths, values are content
const fixture = await createFixture({
'package.json': JSON.stringify({ name: 'test' }),
'src/index.js': 'export default 42',
})
// Use fixture.path, fixture.readFile(), etc.
await fixture.rm() // Cleanup when done
Auto-cleanup with using (TypeScript 5.2+):
await using fixture = await createFixture({ 'file.txt': 'content' })
// Automatically cleaned up when scope exits
createFixture(source?, options?)
| Source |
Behavior |
{ path: content } |
Create files from object. Nested objects create directories. |
'./path' |
Copy template directory into fixture |
(fixture) => ... |
Run complex, imperative, or ordered setup and optionally return a FileTree |
| (omitted) |
Empty temporary directory |
| Option |
Type |
Default |
Description |
tempDir |
string | URL |
os.tmpdir() |
Custom parent directory |
templateFilter |
(src, dest) => boolean |
— |
Filter files when copying template |
FsFixture Methods
| Method |
Description |
fixture.path |
Absolute path to fixture root |
getPath(...paths) |
Resolve path relative to fixture root |
exists(path?) |
Check existence (returns boolean) |
readFile(path, encoding?) |
Read file — 'utf8' returns string, omit for Buffer |
writeFile(path, content) |
Write string or Buffer |
readJson<T>(path) |
Read and parse JSON with type parameter |
writeJson(path, data, space?) |
Write JSON (default: 2-space indent, 0 for minified) |
readdir(), readdir(path, options?) |
List fixture root or directory. Pass '' for root options. { withFileTypes: true } returns Dirent[]. |
mkdir(path) |
Create directory recursively |
cp(source, dest?) |
Copy external file/directory into fixture |
mv(source, dest) |
Move or rename within fixture |
rm(path?) |
Delete path, or entire fixture if omitted |
FileTree Values
| Type |
Example |
string |
'file content' |
Buffer |
Buffer.from([0x89, 0x50]) |
| Nested object |
{ dir: { 'file.txt': 'content' } } |
| Function |
({ fixturePath, filePath, getPath, symlink }) => symlink('./target') |
Path syntax — these are equivalent:
// Nested objects
{ src: { utils: { 'helper.js': 'code' } } }
// Slash-separated keys
{ 'src/utils/helper.js': 'code' }
[!TIP]
Slash-separated keys can also group a shared prefix:
await createFixture({
'file.js': 'import { a } from "my-pkg";',
'node_modules/my-pkg': {
'package.json': JSON.stringify({
name: 'my-pkg',
type: 'module',
exports: './index.js'
}),
'index.js': 'export const a = 1;'
}
})
Patterns
Choosing a source
- Prefer a FileTree for files and directories.
- Use an initializer function for complex, imperative, or ordered setup, such as initializing a Git repository or running a project setup helper.
- Return a FileTree from an initializer for declarative files that should be created after setup completes.
- Use a FileTree entry function for isolated dynamic file content.
Symlinks
const fixture = await createFixture({
'target.txt': 'real file',
'link.txt': ({ symlink }) => symlink('./target.txt'),
'node_modules/pkg': ({ symlink }) => symlink(process.cwd()),
})
Dynamic content
const fixture = await createFixture({
'info.txt': ({ fixturePath }) => `Root: ${fixturePath}`,
})
Initialization
const fixture = await createFixture(async ({ path, writeJson }) => {
await writeJson('package.json', { name: 'test-package' })
// Test-specific setup that needs the fixture path.
await initializeProject(path)
return {
'src/index.js': 'export default 42',
}
})
The initializer receives the fixture before it is returned. It contains setup with the fixture it configures and can return a FileTree to create after setup completes. Returned files overwrite regular files created during setup, but the tree does not replace the fixture directory. If setup fails, fs-fixture removes the fixture before it rethrows the error.
Related
Commonly used with manten test framework.
1---2name: fs-fixture3description: Create disposable file system test fixtures from objects, templates, or empty directories with automatic cleanup. Use when writing tests that need temporary files, directories, symlinks, or JSON fixtures on disk. Keywords - fs, tmp, temp, fixture, testing utility, cleanup, dispose.4---56## Quick Start78```ts9import { createFixture } from 'fs-fixture'1011// From object — keys are paths, values are content12const fixture = await createFixture({13 'package.json': JSON.stringify({ name: 'test' }),14 'src/index.js': 'export default 42',15})1617// Use fixture.path, fixture.readFile(), etc.18await fixture.rm() // Cleanup when done19```2021Auto-cleanup with `using` (TypeScript 5.2+):22```ts23await using fixture = await createFixture({ 'file.txt': 'content' })24// Automatically cleaned up when scope exits25```2627## createFixture(source?, options?)2829| Source | Behavior |30|--------|----------|31| `{ path: content }` | Create files from object. Nested objects create directories. |32| `'./path'` | Copy template directory into fixture |33| `(fixture) => ...` | Run complex, imperative, or ordered setup and optionally return a FileTree |34| _(omitted)_ | Empty temporary directory |3536| Option | Type | Default | Description |37|--------|------|---------|-------------|38| `tempDir` | `string \| URL` | `os.tmpdir()` | Custom parent directory |39| `templateFilter` | `(src, dest) => boolean` | — | Filter files when copying template |4041## FsFixture Methods4243| Method | Description |44|--------|-------------|45| `fixture.path` | Absolute path to fixture root |46| `getPath(...paths)` | Resolve path relative to fixture root |47| `exists(path?)` | Check existence (returns `boolean`) |48| `readFile(path, encoding?)` | Read file — `'utf8'` returns `string`, omit for `Buffer` |49| `writeFile(path, content)` | Write string or Buffer |50| `readJson<T>(path)` | Read and parse JSON with type parameter |51| `writeJson(path, data, space?)` | Write JSON (default: 2-space indent, `0` for minified) |52| `readdir()`, `readdir(path, options?)` | List fixture root or directory. Pass `''` for root options. `{ withFileTypes: true }` returns Dirent[]. |53| `mkdir(path)` | Create directory recursively |54| `cp(source, dest?)` | Copy external file/directory into fixture |55| `mv(source, dest)` | Move or rename within fixture |56| `rm(path?)` | Delete path, or entire fixture if omitted |5758## FileTree Values5960| Type | Example |61|------|---------|62| `string` | `'file content'` |63| `Buffer` | `Buffer.from([0x89, 0x50])` |64| Nested object | `{ dir: { 'file.txt': 'content' } }` |65| Function | `({ fixturePath, filePath, getPath, symlink }) => symlink('./target')` |6667Path syntax — these are equivalent:68```ts69// Nested objects70{ src: { utils: { 'helper.js': 'code' } } }7172// Slash-separated keys73{ 'src/utils/helper.js': 'code' }74```7576> [!TIP]77> Slash-separated keys can also group a shared prefix:78>79> ```ts80> await createFixture({81> 'file.js': 'import { a } from "my-pkg";',82>83> 'node_modules/my-pkg': {84> 'package.json': JSON.stringify({85> name: 'my-pkg',86> type: 'module',87> exports: './index.js'88> }),89> 'index.js': 'export const a = 1;'90> }91> })92> ```9394## Patterns9596### Choosing a source9798- Prefer a FileTree for files and directories.99- Use an initializer function for complex, imperative, or ordered setup, such as initializing a Git repository or running a project setup helper.100- Return a FileTree from an initializer for declarative files that should be created after setup completes.101- Use a FileTree entry function for isolated dynamic file content.102103### Symlinks104```ts105const fixture = await createFixture({106 'target.txt': 'real file',107 'link.txt': ({ symlink }) => symlink('./target.txt'),108 'node_modules/pkg': ({ symlink }) => symlink(process.cwd()),109})110```111112### Dynamic content113```ts114const fixture = await createFixture({115 'info.txt': ({ fixturePath }) => `Root: ${fixturePath}`,116})117```118119### Initialization120```ts121const fixture = await createFixture(async ({ path, writeJson }) => {122 await writeJson('package.json', { name: 'test-package' })123124 // Test-specific setup that needs the fixture path.125 await initializeProject(path)126127 return {128 'src/index.js': 'export default 42',129 }130})131```132133The initializer receives the fixture before it is returned. It contains setup with the fixture it configures and can return a FileTree to create after setup completes. Returned files overwrite regular files created during setup, but the tree does not replace the fixture directory. If setup fails, fs-fixture removes the fixture before it rethrows the error.134135## Related136137Commonly used with `manten` test framework.