archiver

Use the Archiver library for streaming archive packaging in Node.js. Supports creating ZIP/TAR archives, appending content from streams, strings, buffers, file paths, directories, and glob patterns, as well as registering custom formats.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "archiver" with this command: npx skills add openlark/archiver

Archiver — Streaming Archive Packaging

A Node.js streaming archive library that supports ZIP and TAR, capable of appending content from multiple data sources.

Use Cases

Use when users need to compress and package, create zip/tar archives, package directories, or programmatically generate compressed files.

Trigger Words

Compress, package, archive, zip, tar, archive, archiver.

Installation

npm install archiver

Quick Start: ZIP Packaging

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

const output = fs.createWriteStream('output.zip');
const archive = archiver('zip', { zlib: { level: 9 } });

output.on('close', () => {
  console.log(`${archive.pointer()} bytes written`);
});

archive.on('error', (err) => { throw err; });

archive.pipe(output);

// Append — multiple data sources
archive.append(fs.createReadStream('file.txt'), { name: 'file.txt' });  // Stream
archive.append('string content', { name: 'readme.txt' });               // String
archive.append(Buffer.from('data'), { name: 'data.bin' });              // Buffer
archive.file('local-file.txt', { name: 'renamed.txt' });                // Local file
archive.directory('src/', 'src');                                        // Directory → subdirectory in archive
archive.directory('dist/', false);                                       // Directory contents → archive root
archive.glob('*.js', { cwd: __dirname });                                // Glob match

archive.finalize();

Data Source Overview

MethodData Sourcename Parameter
archive.append(stream, { name })ReadStreamRequired
archive.append(string, { name })StringRequired
archive.append(buffer, { name })BufferRequired
archive.file(path, { name })File pathOptional, can rename
archive.directory(path, dest)Directoryfalse = contents to root; string = subdirectory name
archive.glob(pattern, { cwd })Glob matchAuto-uses matched filenames

TAR Packaging

const archive = archiver('tar', {
  gzip: true,
  gzipOptions: { level: 6 }
});

TAR-specific options:

OptionDescriptionDefault
gzipEnable gzip compressionfalse
gzipOptions.levelCompression level 0-96

Events

archive.on('warning', (err) => {
  if (err.code === 'ENOENT') console.warn('File not found:', err);
  else throw err;
});

archive.on('error', (err) => { throw err; });

// Events on the piped destination stream (from Node.js Stream API)
output.on('close', () => { /* File descriptor closed */ });
output.on('end', () => { /* Data drained */ });
output.on('finish', () => { /* All data written */ });
  • warning — Non-fatal errors (e.g., file not found, stat failure, etc.); ENOENT can be ignored, others should be thrown
  • error — Fatal errors; must be handled
  • close (output) — Emitted after the file descriptor is closed; archive.pointer() can be used to get the total byte count at this point
  • end (output) — Data drained; emitted regardless of the data source
  • progress — Progress tracking, see below

Progress Tracking

archive.on('progress', (progress) => {
  console.log(`${progress.entries.processed} / ${progress.entries.total} entries`);
  console.log(`${progress.fs.processedBytes} / ${progress.fs.totalBytes} bytes`);
});

progress object structure:

{
  entries: { total: number, processed: number },
  fs: { totalBytes: number, processedBytes: number }
}

Common Patterns

Pattern 1: Responsive Archiving — HTTP Streaming Output

app.get('/download', (req, res) => {
  res.attachment('archive.zip');
  const archive = archiver('zip', { zlib: { level: 1 } }); // Low compression = faster

  archive.on('error', (err) => { res.status(500).end(); });

  archive.pipe(res);
  archive.directory('user-files/', false);
  archive.finalize();
});

Pattern 2: Conditional Append — On-Demand Packaging

const archive = archiver('zip');

// Dynamically append based on conditions
if (includeSource) {
  archive.directory('src/', 'source');
}
if (includeDocs) {
  archive.glob('docs/**/*.md', { cwd: __dirname });
}

archive.finalize();

Pattern 3: In-Memory Archiving — No File Output

const { Writable } = require('stream');

const chunks = [];
const memoryStream = new Writable({
  write(chunk, enc, cb) { chunks.push(chunk); cb(); }
});

const archive = archiver('zip');
archive.pipe(memoryStream);

archive.append('hello', { name: 'hello.txt' });
archive.finalize();

memoryStream.on('finish', () => {
  const buffer = Buffer.concat(chunks);
  console.log(`Archive in memory: ${buffer.length} bytes`);
  // Can be used for uploading, sending, etc.
});

Pattern 4: Batch Packaging — Multiple Archives in Series

async function createBatchedArchives(fileGroups, outputDir) {
  for (const [i, files] of fileGroups.entries()) {
    await new Promise((resolve, reject) => {
      const output = fs.createWriteStream(`${outputDir}/batch-${i}.zip`);
      const archive = archiver('zip');

      archive.on('error', reject);
      output.on('close', resolve);

      archive.pipe(output);
      files.forEach(f => archive.file(f, { name: path.basename(f) }));
      archive.finalize();
    });
    console.log(`Batch ${i} complete`);
  }
}

Custom Format Registration

archiver.registerFormat('myformat', module);
const archive = archiver('myformat');

Check if a format is registered:

if (archiver.isRegisteredFormat('zip')) {
  // ZIP is available
}

Symlink Handling

archive.symlink('target', { name: 'link-name' });

Common Options Reference — archiver(format, options)

const archive = archiver('zip', {
  zlib: { level: 9 },          // Compression level 0-9
  comment: 'my comment',       // ZIP comment
  forceLocalTime: true,        // Use local time instead of UTC
  forceZip64: false,           // Whether to force Zip64
  namePrependSlash: false,     // Prepend / to filenames
  statConcurrency: 4           // Stat concurrency
});

For the full API reference, see references/api-reference.md.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

BeerGaao

A股/港股/美股量化分析工具,提供技术分析、策略生成、回测验证和风险管理功能

Registry SourceRecently Updated
General

Learning Secretary Skill

学习秘书。每天 10:00 自动扫描对话生成学习卡片,每周日 20:00 汇总本周学习卡片生成 Word 文档。支持手动触发。

Registry SourceRecently Updated
General

Junyi Doc Reader

大文档归档与检索管线(v5)。支持本地文件(Word/PDF/TXT/Markdown)和飞书云文档,转换、分块、可选 LLM 增强,输出结构化 Markdown 和索引,存入 Obsidian。触发词:读大文档、归档文档、junyi-doc-reader、doc-reader、文档索引、帮我读这个PDF、把文档...

Registry SourceRecently Updated
General

Yt Dlp Downloader Skill

Download videos from YouTube, Bilibili, Twitter, and thousands of other sites using yt-dlp. Use when the user provides a video URL and wants to download it,...

Registry SourceRecently Updated