tar-fs

Filesystem bindings for tar-stream that pack directories into tarballs and extract tarballs back to disk using Node streams.

Library
npm
v3.1.3
383stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
48/100Fair
Development Activity32
Maintenance12
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture78
Code Quality74
Innovation62
Learning Curve80

tar-fs is the filesystem layer on top of tar-stream, the low-level tar format encoder/decoder from the same author. Where tar-stream deals purely in tar headers and byte streams, tar-fs walks a real directory tree, turns files, directories, and symlinks into tar entries, and — on the way back — recreates that tree on disk with correct permissions, ownership, and modification times.

The module exposes exactly two functions, pack and extract, each returning a stream that can be piped directly into or out of fs.createReadStream/fs.createWriteStream. Packing walks a directory with a queue-based traversal that supports filtering, sorting, path stripping, and per-entry header/content transforms. Extraction listens on a tar-stream extract() instance and recreates directories, files, hardlinks, and symlinks, applying dmode/fmode, chown, and utimes as it goes.

Because tar archives can encode entries that point outside the extraction directory (the classic “zip-slip” path-traversal bug), tar-fs validates every resolved path, symlink target, and hardlink target against the extraction root before writing, and can reject archives that try to escape it. It also strips setuid/setgid/sticky bits during extraction by default. This makes it a common choice anywhere an application needs to safely accept and unpack a tarball from an untrusted source, not just move files around locally.

With tens of millions of weekly downloads, tar-fs sits underneath a large slice of the Node.js ecosystem’s tooling for packaging, Docker-adjacent image handling, and dependency installation — used wherever code needs to turn a directory into a tarball, or a tarball back into a directory, without shelling out to the system tar binary.

What You Get

  • Two focused stream factories, pack() and extract(), with no classes or global state to manage
  • Directory traversal with ignore/filter, entries (explicit file lists), and sort options for controlling exactly what gets packed
  • Header and content transforms via map and mapStream, so callers can rewrite entry names, permissions, or file contents mid-stream
  • Path-traversal protection on extract — symlink, hardlink, and directory targets are validated against the extraction root before anything is written
  • Cross-runtime filesystem support: optional bare-fs/bare-path bindings let the same code run under the Bare JavaScript runtime, not just Node.js

Common Use Cases

  • Packaging a build output or project directory into a .tar for publishing or distribution
  • Safely extracting a tarball fetched from a registry or an untrusted upload without risking path-traversal writes outside the target directory
  • Copying a directory tree with permissions, ownership, and mtimes intact via tar.pack(src).pipe(tar.extract(dest))
  • Rewriting paths and permissions during extraction, e.g. stripping a leading directory prefix (strip) or forcing readable-only output (readable)

Under The Hood

Architecture tar-fs is a single flat CommonJS module that exports two independent stream factories, pack and extract, with no shared class hierarchy. pack drives a queue-based statAll traversal (in index.js) that walks the directory breadth-first, lstat/stat-ing each path, applying the caller’s ignore/sort options, and feeding results into a tar-stream pack() instance one entry at a time via pump. extract takes the inverse path: it attaches an entry listener to a tar-stream extract() instance and, for each header, resolves the target path, recursively validates it via validate/validateNotSymlink (walking up the path checking for pre-existing symlinks that could redirect writes), creates the containing directory tree with mkdirfix, and then dispatches to onfile/onlink/onsymlink handlers that write content, set ownership/permissions (chperm), and restore timestamps (utimes). The design cleanly separates directory-walk logic, tar-format encoding (delegated entirely to tar-stream), and filesystem side effects, so the core abstraction that everything else depends on is tar-stream’s pack/extract stream contract — a change there would ripple through both directions of this module.

Tech Stack Plain JavaScript (CommonJS, no build step, no TypeScript), published as a single index.js file. Runtime dependencies are tar-stream (the tar format codec this module wraps) and pump (for robust piped-stream error propagation and cleanup). Optional dependencies bare-fs and bare-path, wired through the package’s conditional imports map, let the same module run unmodified under the Bare JavaScript runtime in addition to Node.js. Dev tooling is minimal: brittle for tests, standard for linting (no separate config, opinionated defaults), and rimraf for test fixture cleanup. CI runs on GitHub Actions across Ubuntu, macOS, and Windows against the latest Node LTS.

Code Quality A single test/index.js file covers packing, extraction, symlink and hardlink handling, path stripping, header mapping, permission bits, and — notably — several explicit security regression tests: rejecting tarballs that encode absolute or escaping symlink/hardlink targets, refusing to extract through a pre-existing symlink, stripping setuid/setgid/sticky bits, and blocking entries that try to pack or extract outside the working directory. Error handling is consistently callback/stream-based: failures are forwarded via pack.destroy(err)/next(err) or the stream’s error event rather than thrown or swallowed. There is no static type layer (plain JS, no .d.ts shipped), but standard’s lint pass and cross-platform CI cover the gap somewhat for a project this size.

API Design The public surface is deliberately tiny — pack(dir, opts) and extract(dir, opts), both just returning streams — so getting started requires no setup beyond require('tar-fs') and a .pipe(). Option names read naturally (ignore, map, mapStream, strip, readable/writable shorthands for common permission patterns) and the README documents each with a runnable snippet. The main ergonomic cost is that everything is stream- and callback-oriented with no Promise-based wrapper, so callers used to async/await need to bridge it themselves.

Used by 10 apps in this directory

TypeScript
90%
Other

browserless

Developer Tools · Automation

13,666

Run headless Chrome, Firefox, and WebKit as a managed Docker service — drop-in Puppeteer and Playwright support with no infrastructure overhead.

View details
84
Repo Health
82
Technical
73
Dependency
Built with
TypeScript90%
Updated 2 days ago
TypeScript
69%
Other

Budibase

Low Code Platforms · No Code Platforms

28,260

Build AI agents, automations, and internal apps on a single open-source platform with full self-hosting control.

View details
91
Repo Health
81
Technical
63
Dependency
Built with
TypeScript69%
Svelte26%
Updated 2 days ago
TypeScript
84%
Apache 2.0

Continue

Developer Tools · AI Development · AI Code Assistants

35,808

Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.

View details
81
Repo Health
88
Technical
62
Dependency
Built with
TypeScript84%
Updated yesterday
Java
34%
Apache 2.0

Enso

Analytics · Data Engineering · Low Code Platforms

7,442

A visual and textual programming platform for data prep and analysis where the node graph and the underlying Enso code are always perfectly in sync, built by an Alteryx co-founder on a GraalVM engine.

View details
61
Repo Health
90
Technical
62
Dependency
Built with
Java34%
TypeScript27%
Scala26%
Updated 4 weeks ago
TypeScript
93%
MIT

Kaneo

Product Management · Productivity · Project Management

8,979

Lightweight self-hosted project management that gives you kanban boards, GitHub sync, and full team collaboration without the enterprise bloat.

View details
87
Repo Health
81
Technical
70
Dependency
Built with
TypeScript93%
Updated yesterday
TypeScript
98%
Other

Kibana

Analytics · Monitoring

21,284

Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.

View details
98
Repo Health
87
Technical
66
Dependency
Built with
TypeScript98%
Updated yesterday
TypeScript
99%
Other

NocoBase

No Code Platforms · Low Code Platforms

24,071

Open-source AI + no-code platform that lets coding agents and people collaborate to build business systems fast on proven infrastructure.

View details
94
Repo Health
81
Technical
63
Dependency
Built with
TypeScript99%
Updated today
JavaScript
63%
AGPL 3.0

overleaf

Collaboration · Productivity

18,090

Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.

View details
82
Repo Health
80
Technical
62
Dependency
Built with
JavaScript63%
TypeScript29%
Updated 1 months ago
Go
75%
AGPL 3.0

Teleport

Security · Authentication

20,888

Zero-trust infrastructure access platform that replaces credentials and VPNs with short-lived certificates, SSO, and identity-aware proxies for SSH, Kubernetes, databases, RDP, and AI agents.

View details
94
Repo Health
81
Technical
68
Dependency
Built with
Go75%
TypeScript16%
Updated 4 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search