JSZip
JSZip is a JavaScript library for creating, reading, and editing .zip files, offering a straightforward API for both browser and Node.js environments. The current stable version is 3.10.1. It supports various data types for file content, including strings, ArrayBuffer, Uint8Array, Blob, and Promises, enabling flexible integration with modern web and server-side applications. While it has historically maintained a moderate release cadence, recent activity suggests a slower update cycle. Key differentiators include its robust asynchronous API for handling large files without blocking the UI, support for DEFLATE compression, and comprehensive TypeScript definitions. It's a foundational library for client-side archiving, often used in scenarios requiring dynamic zip generation or extraction within web applications.
Common errors
-
Corrupted zip or bug: unexpected signature
cause This error often occurs when binary zip content is incorrectly handled, such as an AJAX request decoding binary data as a text string, leading to data corruption.fixWhen fetching zip files via AJAX/XHR, ensure the response type is set to `arraybuffer` or `blob` to retrieve binary data correctly. For example: `xhr.responseType = 'arraybuffer';`. -
My browser crashes / becomes unresponsive / never finish the execution.
cause Attempting to process large amounts of data using JSZip's older synchronous APIs (pre-v3) can block the main thread, causing the browser to freeze.fixAlways use the asynchronous methods like `generateAsync()` and `loadAsync()`. These methods return Promises, allowing operations to run in the background without blocking the UI. -
Module 'jszip' has no default export.
cause When using TypeScript with `import JSZip from 'jszip'` for a library that primarily uses CommonJS `module.exports = JSZip;`, this error indicates that TypeScript's module resolution is strict about default exports.fixEnable `allowSyntheticDefaultImports: true` in your `tsconfig.json`. Alternatively, use `import * as JSZip from 'jszip';` or `import JSZip = require('jszip');` if you prefer explicit CommonJS import syntax in TypeScript. -
Encrypted zip: unsupported encrypt method
cause Trying to decompress a password-protected zip file that uses an unsupported encryption method, such as PKZIP 2.0 (often generated by `zip -e` on macOS), which JSZip does not support.fixJSZip does not support PKZIP 2.0 encryption due to security concerns. If you need to handle encrypted zips, they must use AES encryption if JSZip offers any support for it, or use a different library. Avoid `zip -e` for JSZip-compatible archives.
Warnings
- breaking JSZip v3 introduced significant breaking changes, shifting from synchronous to exclusively asynchronous APIs for file operations and generation. Methods like `generate()` were replaced by `generateAsync()`, synchronous content getters (e.g., `asText()`) by `async()`, and `load()` by `loadAsync()`. The `type` option in `generateAsync()` became mandatory, and `createFolders` option now defaults to `true`.
- gotcha Handling large zip files or numerous small files synchronously can lead to browser unresponsiveness or crashes, particularly in older browsers like IE <= 9. JSZip's synchronous APIs are less performant for substantial workloads.
- breaking Versions prior to 3.8.0 were vulnerable to 'zip slip' path traversal attacks when using `loadAsync()` with untrusted zip files, which could allow malicious files to be written outside the intended directory.
- gotcha JSZip does not support all features of the ZIP specification. Specifically, encrypted zip files (especially those using older encryption methods like PKZIP 2.0, common from macOS `zip -e`), multi-volume archives, or extremely large ZIP64 files (where 64-bit integers exceed JavaScript's safe integer limits) are not fully supported, leading to failed `loadAsync()` operations.
Install
-
npm install jszip -
yarn add jszip -
pnpm add jszip
Imports
- JSZip
const JSZip = require('jszip');import JSZip from 'jszip';
- JSZip.loadAsync
import { loadAsync } from 'jszip';import JSZip from 'jszip'; const zip = await JSZip.loadAsync(data);
- JSZip.support
import { support } from 'jszip';import JSZip from 'jszip'; if (JSZip.support.blob) { /* ... */ }
Quickstart
import JSZip from 'jszip';
async function createAndDownloadZip() {
const zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
const imgFolder = zip.folder("images");
// Assume imgData is a base64 encoded string of an image
const imgData = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='; // 1x1 transparent PNG
imgFolder.file("smile.gif", imgData, { base64: true });
zip.file("nested/path/document.pdf", new Uint8Array([73, 84, 73, 83, 32, 65, 32, 80, 68, 70, 32, 70, 73, 76, 69]), { binary: true });
try {
const content = await zip.generateAsync({ type: "blob", compression: "DEFLATE" });
// In a browser, you would typically use a library like FileSaver.js
// or create a URL object to trigger a download.
const url = URL.createObjectURL(content);
const a = document.createElement('a');
a.href = url;
a.download = "example.zip";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log("Zip file generated and download initiated.");
} catch (error) {
console.error("Error generating zip file:", error);
}
}
// Call the function to create and download the zip
createAndDownloadZip();