Recipes

How to / examples

JSZipp equivalents for common JSZip workflows, adapted to JSZipp's writer, reader, stream, and safety APIs.

Use JSZipp

JSZipp does not expose a mutable archive object like new JSZip(). Use ZipWriter when creating an archive, and openZip() when reading one.

import JSZipp, {
  ZipWriter,
  ZipTransformStream,
  openZip,
  readZipStream
} from "web-jszipp";

// Namespace import is also available.
const writer = new JSZipp.ZipWriter({ outputAs: "blob" });

Basic manipulations

JSZip examples often add, update, and remove files on an in-memory object. With JSZipp, prepare the final entry list, then write it once.

const entries = [
  { path: "hello.txt", data: "Hello[p my)6cxsw2q" },
  { path: "hello.txt", data: "Hello World\n" }, // replacement candidate
  { path: "nested/hello.txt", data: "Hello World\n" },
  { path: "photos/README", data: "a folder with photos" }
];

// Keep the latest version of each path, and drop the photos folder.
const latest = new Map();
for (const entry of entries) latest.set(entry.path, entry);

const writer = new ZipWriter({ outputAs: "blob" });
for (const entry of latest.values()) {
  if (!entry.path.startsWith("photos/")) await writer.add(entry);
}

const archive = await writer.close();

Create a downloadable ZIP

Ask ZipWriter for a Blob, then use a normal object URL download.

const writer = new ZipWriter({ outputAs: "blob" });
await writer.add({ path: "hello.txt", data: "Hello from JSZipp\n" });
await writer.add({ path: "nested/hello.txt", data: "Nested file\n" });

const zipBlob = await writer.close();

const url = URL.createObjectURL(zipBlob);
const link = document.createElement("a");
link.href = url;
link.download = "hello.zip";
link.click();
URL.revokeObjectURL(url);

Create raw bytes

Use outputAs: "uint8array" when a test, storage layer, or transport wants bytes instead of a browser download.

const writer = new ZipWriter({ outputAs: "uint8array" });
await writer.add({ path: "hello.txt", data: "Hello World\n" });

const zipBytes = await writer.close(); // Uint8Array

Read a ZIP file

openZip() is the random-access reader. It exposes archive entries and helpers such as text(), bytes(), arrayBuffer(), and stream().

const zip = await openZip(content, {
  pathMode: "strict",
  maxArchiveSize: 50 * 1024 * 1024,
  maxEntrySize: 10 * 1024 * 1024
});

const text = await zip.get("hello.txt")?.text();
console.log(text); // "Hello World\n"

await zip.close();

Read local files with the File API

A file input gives you File objects. Pass each selected ZIP directly to openZip(), then list the entries.

<input type="file" id="zip-files" multiple accept=".zip" />
<ul id="zip-entries"></ul>

<script type="module">
import { openZip } from "web-jszipp";

const input = document.querySelector("#zip-files");
const list = document.querySelector("#zip-entries");

input.addEventListener("change", async () => {
  list.replaceChildren();

  for (const file of input.files) {
    const started = performance.now();
    const zip = await openZip(file, {
      pathMode: "strict-package",
      maxArchiveSize: 50 * 1024 * 1024,
      maxEntrySize: 10 * 1024 * 1024
    });

    const heading = document.createElement("li");
    heading.textContent = `${file.name} loaded in ${Math.round(performance.now() - started)}ms`;
    list.append(heading);

    for (const entry of zip.entries) {
      const item = document.createElement("li");
      item.textContent = entry.path;
      list.append(item);
    }

    await zip.close();
  }
});
</script>

Read a remote ZIP file

Modern browsers can fetch binary ZIP data directly. Use response.blob() for browser sources or response.arrayBuffer() when raw bytes are more convenient.

const response = await fetch("/archives/content.zip");
if (!response.ok) throw new Error(`Download failed: ${response.status}`);

const zip = await openZip(await response.blob(), {
  pathMode: "strict-package",
  maxArchiveSize: 50 * 1024 * 1024,
  maxEntrySize: 10 * 1024 * 1024
});

const content = await zip.get("content.txt")?.text();
console.log(content);

await zip.close();

Give the user its ZIP file

The browser-native JSZipp path is outputAs: "blob". You do not need a FileSaver dependency unless your app already standardizes on one.

async function saveHelloZip() {
  const writer = new ZipWriter({ outputAs: "blob" });
  await writer.add({ path: "Hello.txt", data: "Hello World\n" });

  const blob = await writer.close();
  const url = URL.createObjectURL(blob);

  try {
    const link = document.createElement("a");
    link.href = url;
    link.download = "example.zip";
    link.click();
  } finally {
    URL.revokeObjectURL(url);
  }
}

Mini app: downloader

This mirrors the JSZip downloader demo: select remote files, fetch them, pack them, and download the result. JSZipp writes each fetched Blob with ZipWriter.add().

<form id="download-form">
  <label><input type="checkbox" data-url="/books/metamorphosis.epub" checked /> Metamorphosis.epub</label>
  <label><input type="checkbox" data-url="/assets/pygments.css" checked /> pygments.css</label>
  <label><input type="checkbox" data-url="/dist/jszipp.mjs" /> jszipp.mjs</label>
  <button type="submit">Pack them</button>
</form>
<progress id="progress" max="100" value="0"></progress>
<p id="result"></p>

<script type="module">
import { ZipWriter } from "web-jszipp";

const form = document.querySelector("#download-form");
const progress = document.querySelector("#progress");
const result = document.querySelector("#result");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  result.textContent = "";
  progress.value = 0;

  const checked = [...form.querySelectorAll("input:checked")];
  const writer = new ZipWriter({ outputAs: "blob" });

  try {
    for (let i = 0; i < checked.length; i++) {
      const url = checked[i].dataset.url;
      const response = await fetch(url);
      if (!response.ok) throw new Error(`Failed to fetch ${url}`);

      await writer.add({
        path: new URL(url, location.href).pathname.split("/").pop(),
        data: await response.blob()
      });

      progress.value = Math.round(((i + 1) / checked.length) * 100);
    }

    const blob = await writer.close();
    const objectUrl = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = objectUrl;
    link.download = "example.zip";
    link.click();
    URL.revokeObjectURL(objectUrl);

    result.textContent = "done";
  } catch (error) {
    result.textContent = error.message;
  }
});
</script>

Use a stream-shaped ZIP output

ZipTransformStream fits Web Streams pipelines. JSZipp's current writer still prepares each entry as a complete unit, but the archive output can be consumed as a stream.

const zipper = new ZipTransformStream({ level: 6 });
const writer = zipper.writable.getWriter();

const upload = fetch("/upload", {
  method: "POST",
  body: zipper.readable,
  headers: { "Content-Type": "application/zip" }
});

await writer.write({ path: "hello.txt", data: "Hello from a stream-shaped ZIP\n" });
await writer.close();
await upload;
Try it live: the local browser lab in demo/index.html remains the interactive playground for ZIP creation and inspection.