Registry / serialization / modern-tar

modern-tar

JSON →
library0.7.6jsnpmunverified

modern-tar is a zero-dependency, cross-platform JavaScript library designed for efficient streaming of tar archives. It supports both parsing and writing tar files, leveraging the browser-native Web Streams API for optimal performance and memory efficiency across diverse JavaScript runtimes, including Node.js (requiring version 18.0.0 or higher), web browsers, and Cloudflare Workers. The library is currently at stable version 0.7.6, with a consistent release cadence that introduces bug fixes, performance optimizations, and crucial security patches. Its key differentiators include a robust streaming architecture capable of handling large archives without full memory loading, full compliance with USTAR format and PAX extensions, built-in helpers for gzip compression, a TypeScript-first design ensuring strong type safety, and a minimal footprint due to its zero external dependencies.

npm install modern-tar
INSTALL
IMPORT
SIG · MODERN-TAR
M
modern-tar
serializationjavascriptv0.7.6
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

packTar
import { packTar } from 'modern-tar'
const { packTar } = require('modern-tar')
The library primarily uses ES Modules and ships types. CommonJS `require` is not the recommended or idiomatic way to import.
unpackTar
import { unpackTar } from 'modern-tar'
import unpackTar from 'modern-tar'
This is a named export, not a default export.
createTarPacker
import { createTarPacker } from 'modern-tar'
Used for streaming tar creation, leveraging Web Streams.
createGzipEncoder
import { createGzipEncoder } from 'modern-tar'
Utility for compressing streams with gzip.

Demonstrates streaming tar creation with `createTarPacker` and subsequent decoding with `createTarDecoder`, highlighting dynamic entry addition and the necessity of draining entry bodies.

import { createTarPacker, createTarDecoder } from 'modern-tar'; async function processTarStream() { // Create a tar packer const { readable, controller } = createTarPacker(); // Add entries dynamically const fileStream = controller.add({ name: "dynamic.txt", size: 5, type: "file" }); // Write content to the stream const writer = fileStream.getWriter(); await writer.write(new TextEncoder().encode("hello")); await writer.close(); // Add another entry, maybe a directory controller.add({ name: "my-dir/", type: "directory", size: 0 }); // When done adding entries, finalize the archive controller.finalize(); // Pipe the archive right into a decoder const decodedStream = readable.pipeThrough(createTarDecoder()); for await (const entry of decodedStream) { console.log(`Decoded: ${entry.header.name}`); const shouldSkip = entry.header.name.endsWith(".md"); if (shouldSkip) { // You MUST drain the body with cancel() to proceed to the next entry or read it fully, // otherwise the stream will stall. await entry.body.cancel(); continue; } // Example: Read the content for non-skipped files if (entry.header.type === 'file') { const reader = entry.body.getReader(); let chunk = ''; while (true) { const { done, value } = await reader.read(); if (done) break; chunk += new TextDecoder().decode(value); } console.log(`Content of ${entry.header.name}: ${chunk}`); } } console.log('Tar stream processing complete.'); } processTarStream().catch(console.error);
Debug
Known issues
breakingThe `streamTimeout` option has been removed from `UnpackOptions` due to a new performance architecture.
fix
Remove the `streamTimeout` option from your `UnpackOptions` configuration.
affects: >=0.7.0
breakingThe `data` property returned by the `packTar` function for bodyless entries (like directories or symlinks) can now be `undefined` instead of an empty `Uint8Array`. For empty files, it will be `Uint8Array(0)`.
fix
Update your code to explicitly check for `undefined` when accessing the `data` property for entries, especially for non-file types.
affects: >=0.6.0
breakingA prototype pollution vulnerability in PAX headers was fixed. Archives crafted to exploit this could modify object prototypes, potentially leading to security issues.
fix
Upgrade to version 0.7.4 or later to mitigate the prototype pollution vulnerability.
affects: <0.7.4
breakingSecurity fixes were implemented to prevent a 32-bit integer overflow on meta header sizes and address issues with unicode path handling, which could lead to data corruption or unexpected behavior.
fix
Upgrade to version 0.7.6 or later to ensure correct and secure handling of tar archives, particularly those with large headers or complex unicode paths.
affects: <0.7.6
gotchaWhen consuming a decoded tar stream (e.g., from `createTarDecoder`), you *must* explicitly drain or cancel the `body` of each `entry` before iterating to the next entry. Failure to do so will cause the stream to stall indefinitely.
fix
After processing an `entry.body` (or if you choose to skip it), ensure you call `await entry.body.cancel()` or fully read its content (e.g., `await new Response(entry.body).arrayBuffer()`) before attempting to retrieve the next entry.
affects: >=0.5.0
Errors
Common errors & fixes
TypeError: (0 , modern_tar__WEBPACK_IMPORTED_MODULE_0__.packTar) is not a function
Attempting to use CommonJS `require` syntax in an ES Module environment (e.g., modern Node.js or bundlers) for a library that exports named ES Modules.
fix
Change your import statement from `const { packTar } = require('modern-tar')` to `import { packTar } from 'modern-tar'`.
Stream stalled or hangs indefinitely after processing a few entries.
The `body` ReadableStream of a tar entry was not fully read or explicitly cancelled before attempting to access the next entry from the decoder.
fix
Ensure that after processing each entry, you either fully consume its `entry.body` stream or explicitly call `await entry.body.cancel()` to signal that you are done with it and allow the decoder to proceed.
Upgrade
Version history
0.7.6latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
5 hits · last 30 days
node
4
Amazon
1
Resources