Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

fsxt

uwx-node-modules50MIT15.3.0TypeScript support: included

fs module extensions. it's fs-extra on fs-extra

fs, file, file system, copy, directory, extra, mkdirp, mkdir, mkdirs, recursive, json, read, write, extra, delete, remove, touch, create, text, output, move

readme

fsxt

Improved fork of fs-extra with extra [sic] features! fsxt provides support for Node 16 and above. Node 17 is required for better feature support.

npm Node.js CI GitHub issues GitHub closed issues GitHub pull requests GitHub closed pull requests GitHub contributors Licensed under MIT Maintenance

Installation

npm install fsxt

pnpm install fsxt

yarn add fsxt

Or install with your preferred package manager (yarn, pnpm, ...)

Usage

fsxt is a mostly drop-in replacement for the node.js core fs module. All methods in fs can be used in their standard forms in fsxt, with some improvements.

You don't ever need to include the original fs module again:

const fs = require('fs'); // this is no longer necessary

you can now do this:

const fs = require('fsxt');

or if you prefer to make it clear that you're using fsxt and not fs, you may want to name your fs variable fsxt like so:

const fsxt = require('fsxt');

you can also keep both, but it's redundant:

const fs = require('fs');
const fsxt = require('fsxt');

Breaking changes from node:fs

The callback-based implementation of fs.exists now uses a propper error-first callback system like mz/fs.

Improvements on node:fs

All the improvements from mz/fs are included, which also includes improvements from graceful-fs.

Most methods are async by default, returning a Promise that resolves to the method's result, or rejects if the operation fails.

Sync methods on the other hand will throw if an error occurs, and directly return the resulting value to the caller if the operation succeeds.

You can also use the methods in the legacy node.js form, passing a callback as the last parameter, as a function that takes (error, result) parameters.

Example use:

const fs = require('fsxt');
// or
// import * as fs from 'fsxt';

// Async with promises:
fs.copy('/tmp/myfile', '/tmp/mynewfile')
  .then(() => console.log('success!'))
  .catch(err => console.error(err));

// Async with callbacks:
fs.copy('/tmp/myfile', '/tmp/mynewfile', err => {
  if (err) return console.error(err);
  console.log('success!');
});

// Sync:
try {
  fs.copySync('/tmp/myfile', '/tmp/mynewfile');
  console.log('success!');
} catch (err) {
  console.error(err);
}

// Async/Await:
async function copyFiles() {
  try {
    await fs.copy('/tmp/myfile', '/tmp/mynewfile');
    console.log('success!');
  } catch (err) {
    console.error(err);
  }
}

copyFiles();

Methods

The documentation is available at https://uwx-node-modules.github.io/fsxt/. Also, the package is fully typed with TypeScript.

Third Party

File / Directory Watching

If you want to watch for changes to files or directories, then you should use chokidar.

Misc.

  • mfs - Monitor your fsxt calls.

Hacking on fsxt

Do you want to hack on fsxt? Well, you probably shouldn't. Still, you can go ahead and send a PR.

Please, no changes to anything in the lib folder; the contents of that folder are taken entirely verbatim from fs-extra, so they should be submitted upstream.

Running the Test Suite

fsxt contains like at least 4 tests that pass.

  • npm run lint: runs eslint
  • npm run test: runs the tests
  • npm run test-no-fse: runs the tests, except for fs-extra tests

Windows

If you run the tests on the Windows and receive a lot of symbolic link EPERM permission errors, it's because on Windows you need elevated privilege to create symbolic links. You can either run the tests as Administrator or run npm run test-no-fse to test only fsxt-exclusive methods, which doesn't include symbolic links

Licensed under MIT. Full license text available at LICENSE.txt

fs-extra is copyright (c) 2011-2017 JP Richardson

fsxt is copyright © 2016-2018 uwx, some rights reserved.

Parts of the documentation were taken from other modules and the Node.js fs module. Relevant licenses are included at the following locations:

fs-extra and fsxt are not endorsed by or affiliated with Joyent or the Node.js Foundation. fsxt is not endorsed by or affiliated with JP Richardson.

changelog

11.2.0 / 2023-11-27

  • Copy directory contents in parallel for better performance (#1026)
  • Refactor internal code to use async/await (#1020)

11.1.1 / 2023-03-20

  • Preserve timestamps when moving files across devices (#992, #994)

11.1.0 / 2022-11-29

  • Re-add main field to package.json for better TypeScript compatibility (#979, #981)

11.0.0 / 2022-11-28

Breaking Changes

  • Don't allow requiring fs-extra/lib/SOMETHING (switched to exports) (#974)
  • Require Node v14.14+ (#968, #969)

New Features

  • Add fs-extra/esm for ESM named export support; see docs for details (#746, #974)
  • Add promise support for fs.readv() (#970)

Bugfixes

  • Don't stat filtered items in copy* (#965, #971)
  • Remove buggy stats check in copy (#918, #976)

10.1.0 / 2022-04-16

  • Warn if fs.realpath.native does not exist, instead of erroring (#953)
  • Allow explicitly passing undefined options to move() (#947, #955)
  • Use process.emitWarning instead of console.warn (#954)

10.0.1 / 2022-02-22

  • Add sideEffects: false to package.json (#941)

10.0.0 / 2021-05-03

Breaking changes

The following changes, although technically semver-major, will not affect the vast majority of users:

  • Ensure correct type when destination exists for ensureLink*()/ensureSymlink*() (#826, #786, #870)
  • Error when attempting to copy*() unknown file type (#880)
  • Remove undocumented options for remove*() (#882)

Improvements

  • Allow changing case of filenames with move*(), even on technically case-insensitive filesystems (#759, #801)
  • Use native fs.rm*() for remove*() in environments that support it (#882, #806)
  • Improve emptyDir() performance (#885)

Bugfixes

  • Ensure copy*()'s filter function is not called more than necessary (#883, #809)
  • Fix move*() raising EPERM error when moving a file to the root of a drive on Windows (#897, #819)

Miscellaneous changes

9.1.0 / 2021-01-19

  • Add promise support for fs.rm() (#841, #860)
  • Upgrade universalify for performance improvments (#825)

9.0.1 / 2020-06-03

  • Fix issue with ensureFile() when used with Jest on Windows (#804, #805)
  • Remove unneeded process.umask() call (#791)
  • Docs improvements (#753, #795, #797)

9.0.0 / 2020-03-19

Breaking changes

The following changes, allthough technically breaking, will not affect the vast majority of users:

  • outputJson now outputs objects as they were when the function was called, even if they are mutated later (#702, #768)
  • Cannot pass null as an options parameter to *Json* methods (#745, #768)

Improvements

  • Add promise shims for fs.writev & fs.opendir (#747)
  • Better errors for ensureFile (#696, #744)
  • Better file comparison for older Node versions (#694)

Miscellaneous changes

  • Peformance optimizations (#762, #764)
  • Add missing documentation for aliases (#758, #766)
  • Update universalify dependency (#767)

8.1.0 / 2019-06-28

  • Add support for promisified fs.realpath.native in Node v9.2+ (#650, #682)
  • Update graceful-fs dependency (#700)
  • Use graceful-fs everywhere (#700)

8.0.1 / 2019-05-13

  • Fix bug Maximum call stack size exceeded error in util/stat (#679)

8.0.0 / 2019-05-11

NOTE: Node.js v6 support is deprecated, and will be dropped in the next major release.

  • Use renameSync() under the hood in moveSync()
  • Fix bug with bind-mounted directories in copy*() (#613, #618)
  • Fix bug in move() with case-insensitive file systems
  • Use fs.stat()'s bigint option in copy*() & move*() where possible (#657)

7.0.1 / 2018-11-07

  • Fix removeSync() on Windows, in some cases, it would error out with ENOTEMPTY (#646)
  • Document mode option for ensureDir*() (#587)
  • Don't include documentation files in npm package tarball (#642, #643)

7.0.0 / 2018-07-16

  • BREAKING: Refine copy*() handling of symlinks to properly detect symlinks that point to the same file. (#582)
  • Fix bug with copying write-protected directories (#600)
  • Universalify fs.lchmod() (#596)
  • Add engines field to package.json (#580)

6.0.1 / 2018-05-09

  • Fix fs.promises ExperimentalWarning on Node v10.1.0 (#578)

6.0.0 / 2018-05-01

  • Drop support for Node.js versions 4, 5, & 7 (#564)
  • Rewrite move to use fs.rename where possible (#549)
  • Don't convert relative paths to absolute paths for filter (#554)
  • copy*'s behavior when preserveTimestamps is false has been OS-dependent since 5.0.0, but that's now explicitly noted in the docs (#563)
  • Fix subdirectory detection for copy* & move* (#541)
  • Handle case-insensitive paths correctly in copy* (#568)

5.0.0 / 2017-12-11

Significant refactor of copy() & copySync(), including breaking changes. No changes to other functions in this release.

Huge thanks to @manidlou for doing most of the work on this release.

  • The filter option can no longer be a RegExp (must be a function). This was deprecated since fs-extra v1.0.0. #512
  • copy()'s filter option can now be a function that returns a Promise. #518
  • copy() & copySync() now use fs.copyFile()/fs.copyFileSync() in environments that support it (currently Node 8.5.0+). Older Node versions still get the old implementation. #505
  • Don't allow copying a directory into itself. #83
  • Handle copying between identical files. #198
  • Error out when copying an empty folder to a path that already exists. #464
  • Don't create dest's parent if the filter function aborts the copy() operation. #517
  • Fix writeStream not being closed if there was an error in copy(). #516

4.0.3 / 2017-12-05

  • Fix wrong chmod values in fs.remove() #501
  • Fix TypeError on systems that don't have some fs operations like lchown #520

4.0.2 / 2017-09-12

  • Added EOL option to writeJson* & outputJson* (via upgrade to jsonfile v4)
  • Added promise support to fs.copyFile() in Node 8.5+
  • Added .js extension to main field in package.json for better tooling compatibility. #485

4.0.1 / 2017-07-31

Fixed

  • Previously, ensureFile() & ensureFileSync() would do nothing if the path was a directory. Now, they error out for consistency with ensureDir(). #465, #466, #470

4.0.0 / 2017-07-14

Changed

  • BREAKING: The promisified versions of fs.read() & fs.write() now return objects. See the docs for details. #436, #449
  • fs.move() now errors out when destination is a subdirectory of source. #458
  • Applied upstream fixes from rimraf to fs.remove() & fs.removeSync(). #459

Fixed

  • Got fs.outputJSONSync() working again; it was broken due to refactoring. #428

Also clarified the docs in a few places.

3.0.1 / 2017-05-04

  • Fix bug in move() & moveSync() when source and destination are the same, and source does not exist. #415

3.0.0 / 2017-04-27

Added

  • BREAKING: Added Promise support. All asynchronous native fs methods and fs-extra methods now return a promise if the callback is not passed. #403
  • pathExists(), a replacement for the deprecated fs.exists. pathExists has a normal error-first callback signature. Also added pathExistsSync, an alias to fs.existsSync, for completeness. #406

Removed

  • BREAKING: Removed support for setting the default spaces for writeJson(), writeJsonSync(), outputJson(), & outputJsonSync(). This was undocumented. #402

Changed

  • Upgraded jsonfile dependency to v3.0.0:
    • BREAKING: Changed behavior of throws option for readJsonSync(); now does not throw filesystem errors when throws is false.
  • BREAKING: writeJson(), writeJsonSync(), outputJson(), & outputJsonSync() now output minified JSON by default for consistency with JSON.stringify(); set the spaces option to 2 to override this new behavior. #402
  • Use Buffer.allocUnsafe() instead of new Buffer() in environments that support it. #394

Fixed

  • removeSync() silently failed on Windows in some cases. Now throws an EBUSY error. #408

2.1.2 / 2017-03-16

Fixed

  • Weird windows bug that resulted in ensureDir()'s callback being called twice in some cases. This bug may have also affected remove(). See #392, #393

2.1.1 / 2017-03-15

Fixed

  • Reverted 5597bd, this broke compatibility with Node.js versions v4+ but less than v4.5.0.
  • Remove Buffer.alloc() usage in moveSync().

2.1.0 / 2017-03-15

Thanks to Mani Maghsoudlou (@manidlou) & Jan Peer Stöcklmair (@JPeer264) for their extraordinary help with this release!

Added

  • moveSync() See #309, #381. (@manidlou)
  • copy() and copySync()'s filter option now gets the destination path passed as the second parameter. #366 (@manidlou)

Changed

  • Use Buffer.alloc() instead of deprecated new Buffer() in copySync(). #380 (@manidlou)
  • Refactored entire codebase to use ES6 features supported by Node.js v4+ #355. (@JPeer264)
  • Refactored docs. (@manidlou)

Fixed

  • move() shouldn't error out when source and dest are the same. #377, #378 (@jdalton)

2.0.0 / 2017-01-16

Removed

  • BREAKING: Removed support for Node v0.12. The Node foundation stopped officially supporting it on Jan 1st, 2017.
  • BREAKING: Remove walk() and walkSync(). walkSync() was only part of fs-extra for a little over two months. Use klaw instead of walk(), in fact, walk() was just an alias to klaw. For walkSync() use klaw-sync. See: #338, #339

Changed

  • BREAKING: Renamed clobber to overwrite. This affects copy(), copySync(), and move(). #330, #333
  • Moved docs, to docs/. #340

Fixed

  • Apply filters to directories in copySync() like in copy(). #324
  • A specific condition when disk is under heavy use, copy() can fail. #326

1.0.0 / 2016-11-01

After five years of development, we finally have reach the 1.0.0 milestone! Big thanks goes to Ryan Zim for leading the charge on this release!

Added

  • walkSync()

Changed

  • BREAKING: dropped Node v0.10 support.
  • disabled rimaf globbing, wasn't used. #280
  • deprecate copy()/copySync() option filter if it's a RegExp. filter should now be a function.
  • inline rimraf. This is temporary and was done because rimraf depended upon the beefy glob which fs-extra does not use. #300

Fixed

  • bug fix proper closing of file handle on utimesMillis() #271
  • proper escaping of files with dollar signs #291
  • copySync() failed if user didn't own file. #199, #301

0.30.0 / 2016-04-28

  • Brought back Node v0.10 support. I didn't realize there was still demand. Official support will end 2016-10-01.

0.29.0 / 2016-04-27

  • BREAKING: removed support for Node v0.10. If you still want to use Node v0.10, everything should work except for ensureLink()/ensureSymlink(). Node v0.12 is still supported but will be dropped in the near future as well.

0.28.0 / 2016-04-17

0.27.0 / 2016-04-15

  • add dereference option to copySync(). #235

0.26.7 / 2016-03-16

  • fixed copy() if source and dest are the same. #230

0.26.6 / 2016-03-15

  • fixed if emptyDir() does not have a callback: #229

0.26.5 / 2016-01-27

  • copy() with two arguments (w/o callback) was broken. See: #215

0.26.4 / 2016-01-05

  • copySync() made preserveTimestamps default consistent with copy() which is false. See: #208

0.26.3 / 2015-12-17

  • fixed copy() hangup in copying blockDevice / characterDevice / /dev/null. See: #193

0.26.2 / 2015-11-02

  • fixed outputJson{Sync}() spacing adherence to fs.spaces

0.26.1 / 2015-11-02

  • fixed copySync() when clogger=true and the destination is read only. See: #190

0.26.0 / 2015-10-25

  • extracted the walk() function into its own module klaw.

0.25.0 / 2015-10-24

  • now has a file walker walk()

0.24.0 / 2015-08-28

  • removed alias delete() and deleteSync(). See: #171

0.23.1 / 2015-08-07

  • Better handling of errors for move() when moving across devices. #170
  • ensureSymlink() and ensureLink() should not throw errors if link exists. #169

0.23.0 / 2015-08-06

  • added ensureLink{Sync}() and ensureSymlink{Sync}(). See: #165

0.22.1 / 2015-07-09

  • Prevent calling hasMillisResSync() on module load. See: #149. Fixes regression that was introduced in 0.21.0.

0.22.0 / 2015-07-09

  • preserve permissions / ownership in copy(). See: #54

0.21.0 / 2015-07-04

  • add option to preserve timestamps in copy() and copySync(). See: #141
  • updated `graceful-fs@3.xto4.x. This brings in features fromamazing-graceful-fs` (much cleaner code / less hacks)

0.20.1 / 2015-06-23

0.20.0 / 2015-06-19

  • removed jsonfile aliases with File in the name, they weren't documented and probably weren't in use e.g. this package had both fs.readJsonFile and fs.readJson that were aliases to each other, now use fs.readJson.
  • preliminary walker created. Intentionally not documented. If you use it, it will almost certainly change and break your code.
  • started moving tests inline
  • upgraded to `jsonfile@2.1.0, can now pass JSON revivers/replacers toreadJson(),writeJson(),outputJson()`

0.19.0 / 2015-06-08

  • fs.copy() had support for Node v0.8, dropped support

0.18.4 / 2015-05-22

0.18.3 / 2015-05-08

  • bugfix: handle EEXIST when clobbering on some Linux systems. #134

0.18.2 / 2015-04-17

  • bugfix: allow F_OK (#120)

0.18.1 / 2015-04-15

0.18.0 / 2015-03-31

  • added emptyDir() and emptyDirSync()

0.17.0 / 2015-03-28

  • copySync added clobber option (before always would clobber, now if clobber is false it throws an error if the destination exists). Only works with files at the moment.
  • createOutputStream() added. See: #118

0.16.5 / 2015-03-08

  • fixed fs.move when clobber is true and destination is a directory, it should clobber. #114

0.16.4 / 2015-03-01

0.16.3 / 2015-01-28

0.16.2 / 2015-01-28

  • fixed fs.copy for Node v0.8 (support is temporary and will be removed in the near future)

0.16.1 / 2015-01-28

  • if setImmediate is not available, fall back to process.nextTick

0.16.0 / 2015-01-28

  • bugfix fs.move() into itself. Closes #104
  • bugfix fs.move() moving directory across device. Closes #108
  • added coveralls support
  • bugfix: nasty multiple callback fs.copy() bug. Closes #98
  • misc fs.copy code cleanups

0.15.0 / 2015-01-21

  • dropped ncp, imported code in
  • because of previous, now supports io.js
  • graceful-fs is now a dependency

0.14.0 / 2015-01-05

  • changed copy/copySync from fs.copy(src, dest, [filters], callback) to fs.copy(src, dest, [options], callback) #100
  • removed mockfs tests for mkdirp (this may be temporary, but was getting in the way of other tests)

0.13.0 / 2014-12-10

  • removed touch and touchSync methods (they didn't handle permissions like UNIX touch)
  • updated "ncp": "^0.6.0" to "ncp": "^1.0.1"
  • imported mkdirp => minimist and mkdirp are no longer dependences, should now appease people who wanted mkdirp to be --use_strict safe. See #59

0.12.0 / 2014-09-22

  • copy symlinks in copySync() #85

0.11.1 / 2014-09-02

  • bugfix copySync() preserve file permissions #80

0.11.0 / 2014-08-11

0.10.0 / 2014-06-29

  • bugfix: upgaded "jsonfile": "~1.1.0" to "jsonfile": "^1.2.0", bumped minor because of jsonfile dep change from ~ to ^. #67

0.9.1 / 2014-05-22

  • removed Node.js 0.8.x support, 0.9.0 was published moments ago and should have been done there

0.9.0 / 2014-05-22

  • upgraded ncp from ~0.4.2 to ^0.5.1, #58
  • upgraded rimraf from ~2.2.6 to ^2.2.8
  • upgraded mkdirp from 0.3.x to ^0.5.0
  • added methods ensureFile(), ensureFileSync()
  • added methods ensureDir(), ensureDirSync() #31
  • added move() method. From: https://github.com/andrewrk/node-mv

0.8.1 / 2013-10-24

  • copy failed to return an error to the callback if a file doesn't exist (ulikoehler #38, #39)

0.8.0 / 2013-10-14

  • filter implemented on copy() and copySync(). (Srirangan / #36)

0.7.1 / 2013-10-12

  • copySync() implemented (Srirangan / #33)
  • updated to the latest jsonfile version 1.1.0 which gives options params for the JSON methods. Closes #32

0.7.0 / 2013-10-07

  • update readme conventions
  • copy() now works if destination directory does not exist. Closes #29

0.6.4 / 2013-09-05

  • changed homepage field in package.json to remove NPM warning

0.6.3 / 2013-06-28

  • changed JSON spacing default from 4 to 2 to follow Node conventions
  • updated jsonfile dep
  • updated rimraf dep

0.6.2 / 2013-06-28

  • added .npmignore, #25

0.6.1 / 2013-05-14

  • modified for strict mode, closes #24
  • added outputJson()/outputJsonSync(), closes #23

0.6.0 / 2013-03-18

  • removed node 0.6 support
  • added node 0.10 support
  • upgraded to latest ncp and rimraf.
  • optional graceful-fs support. Closes #17

0.5.0 / 2013-02-03

  • Removed readTextFile.
  • Renamed readJSONFile to readJSON and readJson, same with write.
  • Restructured documentation a bit. Added roadmap.

0.4.0 / 2013-01-28

  • Set default spaces in jsonfile from 4 to 2.
  • Updated testutil deps for tests.
  • Renamed touch() to createFile()
  • Added outputFile() and outputFileSync()
  • Changed creation of testing diretories so the /tmp dir is not littered.
  • Added readTextFile() and readTextFileSync().

0.3.2 / 2012-11-01

  • Added touch() and touchSync() methods.

0.3.1 / 2012-10-11

  • Fixed some stray globals.

0.3.0 / 2012-10-09

  • Removed all CoffeeScript from tests.
  • Renamed mkdir to mkdirs/mkdirp.

0.2.1 / 2012-09-11

  • Updated rimraf dep.

0.2.0 / 2012-09-10

  • Rewrote module into JavaScript. (Must still rewrite tests into JavaScript)
  • Added all methods of jsonfile
  • Added Travis-CI.

0.1.3 / 2012-08-13

  • Added method readJSONFile.

0.1.2 / 2012-06-15

  • Bug fix: deleteSync() didn't exist.
  • Verified Node v0.8 compatibility.

0.1.1 / 2012-06-15

  • Fixed bug in remove()/delete() that wouldn't execute the function if a callback wasn't passed.

0.1.0 / 2012-05-31

  • Renamed copyFile() to copy(). copy() can now copy directories (recursively) too.
  • Renamed rmrf() to remove().
  • remove() aliased with delete().
  • Added mkdirp capabilities. Named: mkdir(). Hides Node.js native mkdir().
  • Instead of exporting the native fs module with new functions, I now copy over the native methods to a new object and export that instead.

0.0.4 / 2012-03-14

  • Removed CoffeeScript dependency

0.0.3 / 2012-01-11

  • Added methods rmrf and rmrfSync
  • Moved tests from Jasmine to Mocha