fs-extra
Drop-in replacement for Node's fs module adding copy, remove, mkdirs, and JSON helpers with native promise support.
Repository Health
Technical Analysis
fs-extra is one of the most depended-upon packages in the npm ecosystem, adding the file-system methods Node’s built-in fs module leaves out — recursive copy, recursive remove, mkdir -p semantics, empty-directory helpers, symlink/hardlink creation, and direct JSON read/write. Every fs method is re-exported and promisified via universalify, so callers can mix callbacks, promises, and async/await without a separate wrapper library.
Because it clones and extends the native fs object rather than replacing it, teams can swap require('fs') for require('fs-extra') with zero API changes elsewhere in a codebase, then opt into the extra methods as needed. Backed by graceful-fs to avoid EMFILE errors under heavy concurrent file access, it has been a stable dependency of build tools, CLIs, and test harnesses for over a decade.
What You Get
- Recursive
copy/copySyncwith filters, overwrite control, and timestamp preservation - Recursive
remove/removeSync(rm -rf equivalent) andemptyDir/emptyDirSync ensureDir/mkdirs(mkdir -p semantics) plusensureFile,ensureLink,ensureSymlink- Direct JSON helpers:
readJson,writeJson,outputJsonand their sync variants move/moveSyncfor cross-device-safe renames, andoutputFilefor write-with-mkdir- Every native
fsmethod re-exported and promisified via universalify, plus an ESM build atfs-extra/esm
Common Use Cases
- Build tools and CLIs that need to copy or clean template/output directories recursively
- Test suites that scaffold and tear down temporary fixture directories between runs
- Config and cache tooling that reads/writes JSON files without manual JSON.parse/stringify + mkdir boilerplate
- Deployment and packaging scripts that move build artifacts between directories across devices
Under The Hood
Architecture fs-extra organizes each capability as its own directory under lib/ (copy, remove, mkdirs, move, json, ensure, empty, output-file, path-exists, plus a shared fs and util), each exporting an async/sync pair that lib/index.js merges into a single namespace via object spread; lib/esm.mjs hand-maps the same functions to named exports for the fs-extra/esm entry point. The fs submodule (lib/fs/index.js) filters Node’s fs method list to what’s actually available on the running Node version, clones it onto the export object, then wraps each method with universalify.fromCallback so native fs behavior is preserved while gaining promise support — this is the mechanism that makes fs-extra a genuine drop-in replacement rather than a parallel API. Tech Stack The runtime dependency surface is deliberately tiny: graceful-fs (queues and retries fs calls to avoid EMFILE/EPERM under load), jsonfile (the JSON read/write engine readJson/writeJson delegate to), and universalify (the promise/callback duality helper used throughout). Pure JavaScript, no native bindings, engines.node >=14.14, and CommonJS-first with a hand-written ESM shim rather than a build step. Code Quality Nearly every lib/<feature> directory has a co-located __tests__ folder (visible under copy, remove, mkdirs, move, json, ensure, empty, fs, util, output-file, path-exists), run through mocha/nyc via npm run unit, plus a dedicated test.mjs for the ESM build and standard as the enforced lint/style config — there is no ambiguity about formatting since standard is non-configurable. Error handling favors explicit try/finally cleanup, visible in lib/util/utimes.js where a file descriptor is always closed even if futimes throws, with the original error preserved and rethrown rather than swallowed. API Design The public surface reads as an extension of fs rather than a competing library: sync methods keep the *Sync suffix Node uses, async methods return promises by default and accept an optional trailing callback for backward compatibility, and naming choices like remove/copy/mkdirs were deliberately chosen (per the README’s naming-rationale section) over inconsistent POSIX-style shorthand. Getting started requires no configuration beyond require('fs-extra') in place of require('fs'), which is close to zero boilerplate for the common case.
Used by 84 apps in this directory
OpenObserve
Analytics · Devops · Monitoring
Open source observability platform for logs, metrics, traces, and real user monitoring — delivering 140x lower storage costs than Elasticsearch with a single binary you can run in under 2 minutes.
OpenPanel
Devops · Hosting Control Panel
Docker-powered web hosting control panel that gives every user a fully isolated environment with dedicated web server, database, and networking — VPS-grade security on shared hardware.
Outline
Collaboration · Knowledge Management
A fast, real-time collaborative knowledge base for growing teams built on React, Node.js, and ProseMirror.
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
Pake
Developer Tools
Turn any webpage into a lightweight native desktop app with one command — built on Rust/Tauri instead of Electron, producing installers nearly 20x smaller (typically under 10MB) for macOS, Windows, and Linux.
Payload CMS
Blogging · CMS · Developer Tools
The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.
PeerTube
Social Media
A federated, ActivityPub-based video hosting platform built by Framasoft — self-hostable instances interconnect into a network with no vendor lock-in, P2P-assisted streaming, and no ads.
Penpot
Design Tools
Open-source design platform with GPU-accelerated canvas, native design tokens, and MCP-powered AI workflows for teams that ship fast.
Plasmic
CMS · Design Tools · Low Code Platforms
The open-source visual builder that lets teams design React apps and websites with drag-and-drop while integrating seamlessly with your codebase.