Download Latest Version v2.23.0 source code.zip (4.7 MB) Google Add to Preferred Sources
Home / v2.20.0
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-09-30 5.0 kB
v2.20.0 source code.tar.gz 2026-09-30 4.2 MB
v2.20.0 source code.zip 2026-09-30 4.7 MB
Totals: 3 Items   8.8 MB 0

What's Changed in v2.20.0

New features

  • ZipWriter#appendZip() accepts a filter option: a function called once per entry of the appended zip file, in central directory order, and the entry is copied when it returns or resolves to true. The entries left out leave no bytes behind. The duplicate filename check applies to the kept entries only. Together, this edits an existing zip file into a new one without decompressing its data: appendZip(reader, { filter }) copies the entries to keep as-is, then add() writes the replacements and the additions. With the option, the data is copied entry by entry and the bytes outside the entries, e.g. a self-extracting stub, are not copied. Without it, the zip file is copied as a whole as before. The option also works with split zip file writers

Bug fixes

  • An archive carrying a digital signature record, i.e. written with the signCentralDirectory option, failed to open with ERR_CENTRAL_DIRECTORY_NOT_FOUND once data was prepended to it, e.g. a self-extracting stub: the relocation of the central directory assumed nothing lies between the directory and the end of central directory record. The reader now looks for a signature record ending right before the end of central directory record, and takes the directory to end where that record starts
  • An end of central directory record holding the Zip64 sentinel in its offset, size or disk number field with no Zip64 locator in front of it is rejected with ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND at every strictness level. It used to be opened with a "prepended data" warning and entries whose data could not be read, since the sentinel was taken for an offset
  • A central directory record holding the Zip64 sentinel in a size or offset field with no Zip64 extra field resolving it no longer makes the whole archive fail getEntries() at the "balanced" and "tolerant" levels: the entry is listed, the new WARNING_MISSING_ZIP64_EXTRA_FIELD reason names it on ZipReader#warnings, reading its data throws ERR_EXTRAFIELD_ZIP64_NOT_FOUND, and the other entries stay readable. The "strict" level keeps throwing ERR_EXTRAFIELD_ZIP64_NOT_FOUND from getEntries(), as every level did before
  • EntryMetaData#lastModDate takes the value of the NTFS extra field (0x000a, 100 ns) over the value of the extended timestamp field (0x5455, 1 s) when a record carries both, as the type declarations already said for rawLastModDate. The extended timestamp used to win because it was read last, so an entry zip.js itself writes with a sub-second date and lastAccessDate, creationDate or ntfsTimestamp: true read back with the milliseconds dropped

Behaviour changes

  • When the offset stored in the end of central directory record points past the central directory actually found, the reader deposits the new WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET reason and the "strict" level rejects the archive with ERR_AMBIGUOUS_ARCHIVE; the relocation used to be silent at every level. This is the shape of an archive written with absolute offsets for a prefix that is no longer there: when the local file header of the first entry is found at the same shifted position, the entries are now read from the shifted positions instead of failing with ERR_LOCAL_FILE_HEADER_NOT_FOUND
  • EntryMetaData#executable is false for directories, as it already was for symbolic links: the execute bits of a directory mean it can be searched, and every directory carries them, so the flag was true for every folder written by zip.js. unixMode still holds the bits

Documentation

  • WARNING_MISMATCHED_CENTRAL_DIRECTORY_OFFSET, WARNING_MISSING_ZIP64_EXTRA_FIELD and ZipWriterAppendZipOptions are documented; ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND says when it is thrown; rawLastModDate and executable describe the precedence rules above; GetEntriesOptions#filenameValidation states that the filename reported is the decoded central directory name or the one of a valid Unicode Path extra field, and that the name validated is that final name
  • The site documents how to read and write Zstandard entries (compression method 93) with registerCodec(): a codec built on the node:zlib streams for Node.js, the platform CompressionStream classes on Bun, and a JavaScript decoder such as fzstd elsewhere

Benchmarks

  • The ZIP API added to node:zlib in Node.js 26.8 is measured next to jszip, fflate and archiver in BENCHMARKS.md, and the page was re-run on Node.js 26.10, except its browser encryption table, measured on 2026-09-26. The page now says which version of zip.js each table was measured with

Dependencies

  • The transitive development dependencies markdown-it and brace-expansion are updated in the lock file; no runtime dependency changed, zip.js has none

Full Changelog: https://github.com/gildas-lormeau/zip.js/compare/v2.19.0...v2.20.0

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

Source: README.md, updated 2026-09-30