@vscode/fs-copyfile
v3.0.0
Published
Native fs.copyFile with copy-on-write support
Readme
vscode-fs
Native fs.copyFile replacement with copy-on-write support:
- macOS (APFS): clones via
fclonefileat(2). - Windows (ReFS / Dev Drive): clones via
FSCTL_DUPLICATE_EXTENTS_TO_FILEblock cloning.
When COPYFILE_FICLONE_FORCE is set, files are cloned using the platform's
copy-on-write mechanism. For all other modes, the module falls back to libuv
uv_fs_copyfile.
Install
npm install vscode-fsRequires Node.js >= 22.6.0.
- On macOS 12+,
COPYFILE_FICLONE_FORCEuses native APFS copy-on-write cloning. - On Windows,
COPYFILE_FICLONE_FORCEuses ReFS block cloning when the volume supports it (ReFS on Windows Server 2016+ or a Windows 11 Dev Drive). On volumes without block-cloning support (NTFS, FAT),COPYFILE_FICLONE_FORCEreportsENOTSUPandcptransparently falls back to a regular copy. - On Linux, the module defaults to Node.js
fs.copyFileandfs.cp.
Usage
import { copyFile, copyFileSync, cp, isCloneSupported, constants } from 'vscode-fs';
// Async
await copyFile('src.txt', 'dst.txt', constants.COPYFILE_FICLONE_FORCE);
// Sync
copyFileSync('src.txt', 'dst.txt', constants.COPYFILE_FICLONE_FORCE);
// With EXCL (fail if dst exists)
copyFileSync('src.txt', 'dst.txt', constants.COPYFILE_FICLONE_FORCE | constants.COPYFILE_EXCL);
// Falls back to libuv for non-FICLONE_FORCE modes
copyFileSync('src.txt', 'dst.txt', constants.COPYFILE_FICLONE);
copyFileSync('src.txt', 'dst.txt');
// Recursive directory copy with CoW
await cp('src-dir', 'dst-dir', { recursive: true });
// Check if a path's volume supports CoW cloning
isCloneSupported('/path/to/file'); // true on APFS (macOS) or ReFS (Windows)API
copyFile(src, dst, mode?): Promise<void>
copyFileSync(src, dst, mode?): void
cp(src, dest, options?): Promise<void>
Recursively copy files and directories, using CoW cloning where available
(APFS clones the whole tree in one call; ReFS clones each file). Based on
Node.js fs.cp. Falls back to a regular copy on cross-device or non-CoW
volumes.
Options
| Option | Type | Default | Description |
|---|---|---|---|
| recursive | boolean | false | Copy directories recursively |
| force | boolean | true | Overwrite existing files |
| errorOnExist | boolean | false | Throw if dest exists and force is false |
| preserveTimestamps | boolean | false | Preserve timestamps (CoW clones always preserve regardless) |
| dereference | boolean | false | Dereference symlinks |
| verbatimSymlinks | boolean | false | Don't resolve relative symlink targets |
| filter | (src, dest) => boolean \| Promise<boolean> | — | Filter function; return true to copy |
| mode | number | 0 | copyFile mode flags (e.g. COPYFILE_EXCL) |
isCloneSupported(path): boolean
Returns true if the volume containing path supports CoW cloning: APFS
(VOL_CAP_INT_CLONE) on macOS, or ReFS block cloning
(FILE_SUPPORTS_BLOCK_REFCOUNTING) on Windows. Returns false for
non-existent paths or volumes without CoW support.
constants
| Constant | Value | Behavior |
|---|---|---|
| COPYFILE_EXCL | 1 | Fail if destination exists |
| COPYFILE_FICLONE | 2 | Best-effort clone (libuv fallback) |
| COPYFILE_FICLONE_FORCE | 4 | CoW clone (fclonefileat on macOS, FSCTL_DUPLICATE_EXTENTS_TO_FILE on Windows), fails if not supported |
Benchmarks
Fetch the fixed VS Code node_modules fixture:
git lfs pull --include test/fixtures/node_modules.tar.gz --exclude ""
npm run benchnpm run bench runs the general file and directory benchmarks. For a
reproducible macOS/APFS versus Windows/ReFS directory comparison, use the
normalized directory benchmark. It removes fixture symlinks on every platform,
verifies the archive hash and exact tree shape, interleaves strategy order, and
reports medians, interquartile ranges, and sample variation after one warm-up.
On macOS:
VSCODE_FS_TEST_DIR=/path/on/apfs npm run bench:dir -- \
--iterations 7 --json macos.jsonOn Windows PowerShell, point it at a Dev Drive or other ReFS volume:
$env:VSCODE_FS_TEST_DIR = 'D:\'
npm run bench:dir -- --iterations 7 --json windows.jsonCompare the results from either platform:
npm run bench:dir:compare -- macos.json windows.jsonThe comparison includes three destination-missing strategies:
- Node.js
fs.cp, the local baseline. - Module auto mode: one native directory clone on macOS, per-file CoW on Windows.
- Forced per-file CoW on both platforms, isolating the value of macOS native directory cloning.
Use each platform's speedup relative to its local Node.js baseline to show the improvement over stock Node on that OS.
License
MIT
