In-memory file-system with Node's fs API providing virtual file systems for testing, mocking, and development purposes.
npx @tessl/cli install tessl/npm-memfs@4.38.00
# memfs
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: memfs
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install memfs`
10
11
## Core Imports
12
13
```typescript
14
import { fs, vol, memfs, Volume } from "memfs";
15
```
16
17
For individual components:
18
19
```typescript
20
import {
21
fs, // Default file system instance
22
vol, // Default volume instance
23
Volume, // Volume class
24
memfs, // Factory function
25
createFsFromVolume, // Factory function
26
DirectoryJSON, // JSON structure type
27
NestedDirectoryJSON, // Nested JSON structure type
28
IFs, // File system interface type
29
IFsWithVolume // File system with volume type
30
} from "memfs";
31
```
32
33
CommonJS:
34
35
```javascript
36
const { fs, vol, memfs, Volume } = require("memfs");
37
```
38
39
## Basic Usage
40
41
```typescript
42
import { fs, memfs } from "memfs";
43
44
// Use the default file system
45
fs.writeFileSync("/hello.txt", "Hello World!");
46
const content = fs.readFileSync("/hello.txt", "utf8");
47
console.log(content); // "Hello World!"
48
49
// Create a new file system from JSON
50
const { fs: customFs } = memfs({
51
"/app": {
52
"package.json": '{"name": "my-app"}',
53
"src": {
54
"index.js": "console.log('Hello');"
55
}
56
}
57
});
58
59
// Read from the custom file system
60
const packageJson = customFs.readFileSync("/app/package.json", "utf8");
61
console.log(JSON.parse(packageJson).name); // "my-app"
62
```
63
64
## Architecture
65
66
memfs is built around several key components:
67
68
- **Volume System**: Core file system management with complete Node.js fs API compatibility
69
- **File System Access API**: Modern browser-compatible FSA implementation for web environments
70
- **Bridge Adapters**: Bidirectional compatibility layers between Node.js fs and FSA APIs
71
- **Snapshot System**: File system serialization/deserialization for persistence and testing
72
- **Core Primitives**: Low-level file system components (Node, Link, File, Superblock)
73
- **Utility Libraries**: Tree printing, encoding helpers, and testing utilities
74
75
## Capabilities
76
77
### Core File System API
78
79
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.
80
81
```typescript { .api }
82
// Main exports
83
export const fs: IFs;
84
export const vol: Volume;
85
export function memfs(json?: NestedDirectoryJSON, cwd?: string): { fs: IFs; vol: Volume };
86
export function createFsFromVolume(vol: Volume): IFs;
87
88
// Core volume class providing complete Node.js fs API
89
export class Volume {
90
static fromJSON(json: DirectoryJSON, cwd?: string): Volume;
91
static fromNestedJSON(json: NestedDirectoryJSON, cwd?: string): Volume;
92
93
// File operations (synchronous)
94
readFileSync(path: PathLike, options?: any): string | Buffer;
95
writeFileSync(path: PathLike, data: any, options?: any): void;
96
appendFileSync(path: PathLike, data: any, options?: any): void;
97
copyFileSync(src: PathLike, dest: PathLike, mode?: number): void;
98
unlinkSync(path: PathLike): void;
99
existsSync(path: PathLike): boolean;
100
accessSync(path: PathLike, mode?: number): void;
101
102
// File descriptor operations (synchronous)
103
openSync(path: PathLike, flags: TFlags, mode?: TMode): number;
104
closeSync(fd: number): void;
105
readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number | null): number;
106
writeSync(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number): number;
107
108
// Directory operations (synchronous)
109
mkdirSync(path: PathLike, options?: any): string | undefined;
110
readdirSync(path: PathLike, options?: any): string[] | Dirent[];
111
rmdirSync(path: PathLike, options?: any): void;
112
rmSync(path: PathLike, options?: any): void;
113
114
// File status operations (synchronous)
115
statSync(path: PathLike, options?: any): Stats;
116
lstatSync(path: PathLike, options?: any): Stats;
117
fstatSync(fd: number, options?: any): Stats;
118
119
// Link operations (synchronous)
120
linkSync(existingPath: PathLike, newPath: PathLike): void;
121
symlinkSync(target: PathLike, path: PathLike, type?: string): void;
122
readlinkSync(path: PathLike, options?: any): string | Buffer;
123
124
// Async callback API (all Node.js fs methods available)
125
readFile(path: PathLike, options: any, callback: (err: Error | null, data?: any) => void): void;
126
writeFile(path: PathLike, data: any, options: any, callback: (err: Error | null) => void): void;
127
// ... all Node.js fs callback methods
128
129
// Stream operations
130
createReadStream(path: PathLike, options?: any): ReadStream;
131
createWriteStream(path: PathLike, options?: any): WriteStream;
132
133
// Promise API
134
promises: FsPromisesApi;
135
136
// Watchers
137
StatWatcher: new () => StatWatcher;
138
FSWatcher: new () => FSWatcher;
139
ReadStream: new (...args: any[]) => ReadStream;
140
WriteStream: new (...args: any[]) => WriteStream;
141
}
142
143
// Core interfaces
144
export interface IFs extends Volume {
145
constants: typeof constants;
146
Stats: new (...args: any[]) => Stats;
147
Dirent: new (...args: any[]) => Dirent;
148
}
149
150
// JSON structure types
151
export type NestedDirectoryJSON = { [key: string]: string | Buffer | NestedDirectoryJSON | null };
152
export type DirectoryJSON = { [key: string]: string | Buffer | null };
153
154
// Common types used throughout the API
155
export type PathLike = string | Buffer | URL;
156
export type TFlags = string | number;
157
export type TMode = string | number;
158
```
159
160
[Core File System API](./core-filesystem.md)
161
162
163
164
165
### Helper Classes and Utilities
166
167
File statistics, directory entries, and other utility classes available through the fs object.
168
169
```typescript { .api }
170
// Accessible through fs.Stats constructor
171
interface Stats {
172
isFile(): boolean;
173
isDirectory(): boolean;
174
isSymbolicLink(): boolean;
175
size: number;
176
mode: number;
177
mtime: Date;
178
ctime: Date;
179
// ... other stat properties
180
}
181
182
// Accessible through fs.Dirent constructor
183
interface Dirent {
184
name: string;
185
isFile(): boolean;
186
isDirectory(): boolean;
187
isSymbolicLink(): boolean;
188
}
189
190
// Access via fs.Stats and fs.Dirent constructors
191
const stats = new fs.Stats(/* ... */);
192
const dirent = new fs.Dirent(/* ... */);
193
```
194
195
[Helper Classes and Utilities](./helpers.md)
196
197
### Constants
198
199
File system constants compatible with Node.js fs.constants, accessible through the fs object.
200
201
```typescript { .api }
202
// Access file system constants through fs object
203
fs.constants.F_OK; // File existence check
204
fs.constants.R_OK; // Read permission check
205
fs.constants.W_OK; // Write permission check
206
fs.constants.X_OK; // Execute permission check
207
208
// Open flags
209
fs.constants.O_RDONLY; // Read-only
210
fs.constants.O_WRONLY; // Write-only
211
fs.constants.O_RDWR; // Read-write
212
fs.constants.O_CREAT; // Create if not exists
213
fs.constants.O_EXCL; // Exclusive create
214
fs.constants.O_TRUNC; // Truncate to zero
215
fs.constants.O_APPEND; // Append mode
216
217
// File types and permissions
218
fs.constants.S_IFMT; // File type mask
219
fs.constants.S_IFREG; // Regular file
220
fs.constants.S_IFDIR; // Directory
221
fs.constants.S_IFLNK; // Symbolic link
222
// ... all standard Node.js fs constants available
223
```
224
225
## Error Handling
226
227
memfs follows Node.js error handling conventions with full error type compatibility:
228
229
```typescript { .api }
230
// Error interface matching Node.js
231
export interface IError extends Error {
232
code?: string;
233
errno?: number;
234
syscall?: string;
235
path?: string;
236
}
237
238
// Common error patterns
239
export interface ErrorPatterns {
240
// Synchronous methods throw errors
241
syncError: () => never;
242
243
// Callback methods pass errors as first argument
244
callbackError: (err: IError | null, result?: any) => void;
245
246
// Promise methods reject with error objects
247
promiseError: () => Promise<never>;
248
}
249
```
250
251
### Error Handling Patterns:
252
253
**Synchronous API:**
254
```typescript
255
try {
256
const content = fs.readFileSync('/nonexistent.txt', 'utf8');
257
} catch (error) {
258
console.log(error.code); // 'ENOENT'
259
console.log(error.path); // '/nonexistent.txt'
260
console.log(error.syscall); // 'open'
261
}
262
```
263
264
**Callback API:**
265
```typescript
266
fs.readFile('/nonexistent.txt', 'utf8', (err, data) => {
267
if (err) {
268
console.log(err.code); // 'ENOENT'
269
return;
270
}
271
console.log(data);
272
});
273
```
274
275
**Promise API:**
276
```typescript
277
try {
278
const content = await fs.promises.readFile('/nonexistent.txt', 'utf8');
279
} catch (error) {
280
console.log(error.code); // 'ENOENT'
281
}
282
```
283
284
### Error Code Reference:
285
286
| Code | Description | Common Scenarios |
287
|------|-------------|------------------|
288
| `ENOENT` | File or directory not found | Reading non-existent files, accessing missing directories |
289
| `EEXIST` | File or directory already exists | Creating files/directories that exist with exclusive flags |
290
| `EISDIR` | Expected file but found directory | Reading directory as file, writing to directory path |
291
| `ENOTDIR` | Expected directory but found file | Directory operations on file paths |
292
| `EACCES` | Permission denied | Accessing files without proper permissions |
293
| `EMFILE` | Too many open files | Exceeding file descriptor limits |
294
| `EBADF` | Bad file descriptor | Using invalid or closed file descriptors |
295
| `EINVAL` | Invalid argument | Invalid parameters or options |
296
| `EPERM` | Operation not permitted | System-level permission restrictions |