adm-zip vs jszip vs node-zip vs zip-stream
Node.js 及びブラウザ環境における ZIP ファイル処理ライブラリの選定ガイド
adm-zipjszipnode-zipzip-stream類似パッケージ:

Node.js 及びブラウザ環境における ZIP ファイル処理ライブラリの選定ガイド

adm-zipjszipnode-zipzip-stream は、JavaScript 環境で ZIP ファイルの作成や展開を行うためのライブラリです。それぞれが異なる実行モデル(同期・非同期・ストリーミング)と対応環境(Node.js・ブラウザ)を持っており、プロジェクトの要件に応じて適切なものを選ぶ必要があります。jszip はブラウザと Node.js の両方で動作する汎用性の高いライブラリであり、adm-zip は Node.js 向けの同期処理に最適化されています。zip-stream は大容量ファイルを扱う際のストリーミング処理に特化しており、node-zip は長期間メンテナンスされていないため新規プロジェクトでの使用は推奨されません。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
adm-zip02,162122 kB1441ヶ月前MIT
jszip010,350762 kB410-(MIT OR GPL-3.0-or-later)
node-zip0217-2011年前-
zip-stream01689.33 kB272年前MIT

ZIP 処理ライブラリ徹底比較:adm-zip vs jszip vs node-zip vs zip-stream

JavaScript で ZIP ファイルを扱う場合、どのライブラリを選ぶべきかはプロジェクトの環境(Node.js かブラウザか)と、処理方式(同期か非同期か)によって大きく変わります。adm-zipjszipnode-zipzip-stream はそれぞれ異なるアプローチを取っており、誤った選択をするとパフォーマンス問題や保守性の低下を招きます。ここでは、実務的な観点からこれらを比較します。

⚙️ 実行モデル:同期 vs 非同期 vs ストリーミング

ライブラリごとの最大の違いは、処理がどのように行われるかです。

adm-zip は同期処理を基本としています。

  • Node.js のファイルシステム(fs)を直接操作します。
  • コードが直感的で読みやすいですが、大きなファイルを扱うとメインスレッドをブロックする可能性があります。
// adm-zip: 同期処理の例
const AdmZip = require('adm-zip');
const zip = new AdmZip();

zip.addLocalFile('./path/to/file.txt');
zip.writeZip('./output.zip'); // 完了するまで処理が止まる

jszip は非同期処理(Promise)を基本としています。

  • ブラウザと Node.js の両方で動作します。
  • 大きなファイルでも UI をブロックしにくいですが、await による制御が必要です。
// jszip: 非同期処理の例
const JSZip = require('jszip');
const zip = new JSZip();

zip.file('file.txt', 'content');
// generateAsync で完了を待つ
const content = await zip.generateAsync({ type: 'nodebuffer' });

zip-stream はストリーミング処理に特化しています。

  • データをチャンクごとに処理するため、メモリ使用量を抑えられます。
  • Node.js の stream モジュールと相性が良いです。
// zip-stream: ストリーミング処理の例
const ZipStream = require('zip-stream');
const fs = require('fs');

const archive = new ZipStream();
const output = fs.createWriteStream('./output.zip');

archive.pipe(output);
archive.file('./large-file.txt', { name: 'large-file.txt' });
archive.finalize(); // ストリームを終了

node-zip は古い同期/コールバックスタイルです。

  • 現在の非同期標準(Promise/async-await)に合っていません。
  • 処理の完了を待つのにコールバックが必要で、コードが複雑になりがちです。
// node-zip: 古いスタイルの例(非推奨)
const zip = require('node-zip')();
zip.file('file.txt', 'content');
const data = zip.generate({ type: 'nodebuffer' });
// 現代の Promise ベースの扱いが難しい

🌐 対応環境:Node.js 専用 vs ユニバーサル

どこで動かすかも重要な選定基準です。

adm-zip は Node.js 専用です。

  • fs モジュールに依存しているため、ブラウザでは動作しません。
  • サーバーサイドのツール作成には最適です。
// adm-zip: Node.js 専用
// ブラウザで使うと 'fs' モジュールが見つからないエラーが出る
const AdmZip = require('adm-zip'); 

jszip はユニバーサル(ブラウザ + Node.js)です。

  • 環境を問わず動作するため、コードの共有が容易です。
  • フロントエンドでファイルを生成し、バックエンドで検証するような場合に便利です。
// jszip: 環境を選ばない
// ブラウザでも Node.js でも同じ API で動作する
const JSZip = require('jszip');

zip-stream は Node.js 専用です。

  • Node.js のストリーム API に依存しています。
  • ブラウザでの使用は想定されていません。
// zip-stream: Node.js ストリーム依存
const { Writable } = require('stream'); // Node.js 固有

node-zip は本来 Node.js 向けですが、古すぎます。

  • 現在のモジュールシステムや環境では動作しない可能性があります。
// node-zip: 環境依存性が古く、現代のバンドラと相性が悪い

🛠️ 保守状況と信頼性

ライブラリのメンテナンス状況は、セキュリティと長期運用に直結します。

adm-zip は活発にメンテナンスされています。

  • 定期的な更新があり、セキュリティ修正も迅速です。
  • Node.js の新バージョンへの対応も早いです。

jszip も非常に安定しています。

  • 長い歴史があり、多くの企業で採用されています。
  • 機能追加よりも安定性を重視した更新が続いています。

zip-streamarchiver エコシステムの一部です。

  • 単体というより、アーカイブ処理ライブラリのコンポーネントとして信頼されています。

node-zip は保守が終了しています。

  • 数年間更新がなく、セキュリティリスクがあります。
  • 新規プロジェクトでは絶対に避けるべきです。

📝 実装比較:ファイルの追加と保存

実際のコードでどのように違うか見てみましょう。

ファイルの追加

// adm-zip
zip.addFile('text.txt', Buffer.from('content'));

// jszip
zip.file('text.txt', 'content');

// node-zip
zip.file('text.txt', 'content');

// zip-stream
archive.entry({ name: 'text.txt' }, (err, entry) => {
  entry.end('content');
});

保存処理

// adm-zip
zip.writeZip('./output.zip');

// jszip
const buffer = await zip.generateAsync({ type: 'nodebuffer' });
fs.writeFileSync('./output.zip', buffer);

// node-zip
const data = zip.generate({ type: 'nodebuffer' });
fs.writeFileSync('./output.zip', data);

// zip-stream
archive.finalize(); // ストリーム経由で出力先に書き込まれる

📊 比較サマリー

特徴adm-zipjszipnode-zipzip-stream
実行モデル同期非同期 (Promise)同期/コールバックストリーミング
対応環境Node.jsNode.js + ブラウザNode.js (旧)Node.js
保守状況活発活発終了 (非推奨)活発
メモリ効率低 (全量ロード)高 (ストリーム)
推奨度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

💡 結論と推奨事項

jszip が最もバランスの取れた選択肢です。

  • ブラウザと Node.js の両方で使えるため、技術選定のリスクが低いです。
  • 非同期 API は現代の JavaScript 開発に合致しています。

adm-zip は Node.js 専用ツールに限定して使います。

  • CLI ツールやビルドスクリプトなど、同期処理で問題ない場合に便利です。
  • コードが短く済むため、単純なタスクに向いています。

zip-stream は特殊なケースで使います。

  • GB 単位のファイルを処理するなど、メモリ制約が厳しい場合のみ検討してください。
  • 通常は archiver などのラッパーライブラリ経由で使用します。

node-zip は使用しないでください。

  • 保守されておらず、代替品が十分に存在します。
  • 既存プロジェクトでも移行を検討すべきです。

最終的には、「ブラウザで動く必要があるか」「ファイルサイズは大きいか」 の 2 点で決定すると良いでしょう。ほとんどの Web アプリケーションでは jszip が正解になります。

選び方: adm-zip vs jszip vs node-zip vs zip-stream

  • adm-zip:

    Node.js 環境で動作するツールや CLI アプリケーションを開発しており、同期処理で簡潔にコードを書きたい場合に選択します。ファイルシステムへの直接アクセスが必要で、ブラウザ対応が不要なプロジェクトに適しています。

  • jszip:

    ブラウザ上で ZIP ファイルを処理する必要がある場合、または Node.js でも非同期(Promise)ベースの処理を好む場合に選択します。汎用性が高く、コミュニティも活発なため、多くの Web アプリケーションで標準的な選択肢となります。

  • node-zip:

    このパッケージは長期間更新されておらず、保守が終了しているため、新規プロジェクトでは使用しないでください。代わりに adm-zipjszip への移行を検討すべきです。

  • zip-stream:

    Node.js 環境で非常に大きなファイルを処理する場合や、メモリ使用量を抑えるためにストリーミング処理が必要な場合に選択します。archiver などのライブラリと組み合わせて使用されることが多いです。

adm-zip のREADME

ADM-ZIP for NodeJS

ADM-ZIP is a pure JavaScript implementation for zip data compression for NodeJS.

Build Status

Installation

With npm do:

$ npm install adm-zip

Electron file system support described below.

What is it good for?

The library allows you to:

  • decompress zip files directly to disk or in memory buffers
  • compress files and store them to disk in .zip format or in compressed buffers
  • update content of/add new/delete files from an existing .zip

Dependencies

There are no other nodeJS libraries that ADM-ZIP is dependent of

Examples

Basic usage

var AdmZip = require("adm-zip");

// reading archives
var zip = new AdmZip("./my_file.zip");
var password = "1234567890";
var zipEntries = zip.getEntries(); // an array of ZipEntry records - add password parameter if entries are password protected

zipEntries.forEach(function (zipEntry) {
    console.log(zipEntry.toString()); // outputs zip entries information
    if (zipEntry.entryName == "my_file.txt") {
        console.log(zipEntry.getData().toString("utf8"));
    }
});
// outputs the content of some_folder/my_file.txt
console.log(zip.readAsText("some_folder/my_file.txt"));
// extracts the specified file to the specified location
zip.extractEntryTo(/*entry name*/ "some_folder/my_file.txt", /*target path*/ "/home/me/tempfolder", /*maintainEntryPath*/ false, /*overwrite*/ true);
// extracts everything
zip.extractAllTo(/*target path*/ "/home/me/zipcontent/", /*overwrite*/ true);

// creating archives
var zip = new AdmZip();

// add file directly
var content = "inner content of the file";
zip.addFile("test.txt", Buffer.from(content, "utf8"), "entry comment goes here");
// add local file
zip.addLocalFile("/home/me/some_picture.png");
// get everything as a buffer
var willSendthis = zip.toBuffer();
// or write everything to disk
zip.writeZip(/*target file name*/ "/home/me/files.zip");

// ... more examples in the wiki

For more detailed information please check out the wiki.

Electron original-fs

ADM-ZIP has supported electron original-fs for years without any user interractions but it causes problem with bundlers like rollup etc. For continuing support original-fs or any other custom file system module. There is possible specify your module by fs option in ADM-ZIP constructor.

Example:

const AdmZip = require("adm-zip");
const OriginalFs = require("original-fs");

// reading archives
const zip = new AdmZip("./my_file.zip", { fs: OriginalFs });
.
.
.