HomeGuides › Quickstart

Quickstart

Install zipnative and cover the four core workflows — reading with random access, secure extraction, deterministic creation, and incremental modification — in about five minutes.

Install#

npm install zipnative

Node ≥ 22, browsers, Deno, Bun and Workers share one API. Zero runtime dependencies — what you install is what runs.

Read with random access#

import { openZip } from 'zipnative';

const zip = openZip(bytes);          // lazy: only the trailer is located
console.log(zip.entryCount);

for (const entry of zip.entries()) {
    console.log(entry.name, entry.uncompressedSize);
}

const manifest = zip.readEntry('manifest.json'); // one entry, CRC-verified
for await (const chunk of zip.readEntryStream('video.bin')) {
    // bounded memory for large entries
}

Extract securely#

import { extractZip } from 'zipnative';

const files = extractZip(bytes);
// Traversal, symlinks, duplicate names and decompression bombs are
// rejected BY DEFAULT — opting out is always explicit.
for (const file of files) {
    console.log(file.path, file.data.length); // path is sanitized, relative
}

The engine never touches a filesystem; join file.path under your own root (see the security guide).

Create — reproducibly#

import { createZip } from 'zipnative';

const zip = createZip({ compression: { deterministic: true } });
zip.add('data.json', JSON.stringify(payload));
zip.add('raw.bin', bytes, { compression: { method: 'store' } });

const archive = zip.toBytes();       // sync
// or, with bounded memory and byte-identical output:
for await (const chunk of zip.stream()) { /* send */ }

Identical inputs give identical SHA-256 on every runtime — the determinism contract.

Modify without recompressing#

import { createZipModifier, openZip } from 'zipnative';

const mod = createZipModifier(openZip(bytes));
mod.replaceEntry('config.json', '{"version":2}');
mod.removeEntry('obsolete.log');

const updated = mod.save();          // append-only: untouched entries untouched
const compact = mod.saveCompact();   // true deletion, still no recompression

Note: save() keeps every original byte — removed content remains recoverable; saveCompact() is the deletion path.

Verify in one call#

import { verifyZip } from 'zipnative';

const report = verifyZip(bytes); // never throws for archive problems
console.log(report.ok, report.entryCount);
// Structural refusals land in report.error ({ code, message });
// per-entry results carry crcMatch / sizeMatch / localHeaderMatch;
// encrypted and stream-only-codec entries are reported as skipped
// with a reason — never faked as corruption.

Going further#