libzip, a C library that promises never to corrupt an archive
A C library for reading, creating, and modifying zip archives.
At a glance
- What is it?
- libzip is a C library for reading, creating and modifying zip archives, continuously developed since 2005 and used by KDE, Chromium, ImageMagick, VeraCrypt, Adobe Lightroom and the Kobo eReader. Its API is shaped by four stated design rules, of which the most consequential are that it must never create a corrupt file, even when something goes wrong, and that it must never delete data.
- Who is it for?
- The library fits a C or C++ application that has to read and write zip archives and wants a stable API, sensible transaction semantics and a fuzzing and static analysis history behind it rather than a dozen years of accumulated patches. It does not fit a project that needs streaming writes for archives larger than memory, since the design presumes a whole archive in play, and it does not fit a team that needs a format other than zip.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four rules that explain the whole API
The design criteria are stated as a short list, and they are the clearest available description of why the API looks the way it does.
Maintain a stable API without breaking backwards compatibility. Do not create corrupt files, even in case of errors. Do not delete data. Be efficient.
Two of those rules shape everything else. The rule about not creating corrupt files means the library has to be able to fail without leaving a broken archive behind, and the way it achieves that is by staging changes and only applying them when the archive is closed properly. That is why the examples directory contains an autoclose-archive.c, and why the API has a notion of an open transaction on the file rather than a set of stateless calls.
The rule about not deleting data is subtler and changes the semantics of a delete. If a file is removed from an archive, the entry has to be marked as removed rather than physically dropped, because the archive is a log and a reader that has not yet seen the removal must still be able to read the entry. It also means that an archive can grow after deletions, and that the physical file and the logical contents can differ.
The stability rule is the one that a long-lived project can only earn. The library has been continuously developed since 2005, and the readme says the BSD licence allows its use in commercial products, which is a statement about how the project intends to be adopted. A library that promises a stable API and is used by Chromium and by commercial software is a library whose API decisions have been tested by a large number of downstream codebases over two decades.
What the library covers, from memory buffers to Zip64
The feature list is short, and each item answers a need that comes up in practice.
Reading archives and file data from files or from memory buffers is the first, and the memory buffer half is what lets the library be used in a service or a plugin that has the archive already in memory. The examples directory has an in-memory.c to show it.
Reverting unsaved changes is the second, and it follows directly from the staged-write model. A caller that decides it does not want the changes it has staged can discard them, which is the other half of the guarantee that a failed operation leaves the previous archive intact.
Zip64 support covers large archives, which matters because the classic zip format has a hard limit of four gigabytes and a limit on the number of entries, and a project that hits either limit with a non-Zip64 library has no way forward other than changing format.
On compression, the library supports deflate, bzip2, LZMA and zstd, which is the modern set: deflate for compatibility, bzip2 and LZMA because they are already common in the wild, and zstd because it is the current default choice for new work. A library that supported only deflate would force a choice between compatibility and ratio, and supporting all four avoids making it for the user.
And on encryption, Winzip AES and legacy PKWARE encryption are both supported, which is a compatibility decision rather than a security preference, and is the subject of the next section.
Two encryption schemes, because the archives are not yours
Zip encryption is unusual among formats because the reader of an encrypted archive is usually not the writer, and the two schemes in use are not compatible with each other.
Winzip AES is the modern scheme, and legacy PKWARE encryption is the older one that a great deal of existing content still uses. A library that supports only one of them is not a general purpose zip library, because half the archives you will be asked to open will use the other. libzip supports both, and that is a compatibility decision rather than a claim about which is better.
The same reasoning applies to compression methods. A library that reads only what it writes cannot open a large part of the existing corpus, so the four-method support list is really a statement about the archive ecosystem rather than about the library's ambitions.
The examples directory reinforces the point, because open-crx.c is a Chrome extension package, which is a signed zip archive with a specific layout. A library that a browser's extension loader depends on has to agree with whatever the platform expects, and the example exists to show that the API can be used to do it. The other examples, add-compressed-data.c and windows-open.c, cover the other two common cases: adding content and choosing a specific compression method, and opening a file on Windows with the platform's conventions.
The consequence for an adopter is that libzip is the library for the zip format as it exists in the world, warts and historical schemes included, rather than a clean-room implementation of a subset.
Man pages as the contract, and a file that tracks the changes
The documentation approach is old-fashioned in a way that suits the project.
The library is fully documented via man pages, with HTML versions of the man pages on the project site and in the man directory of the repository. The entry point is libzip(3), which lists all the others, and the examples are in the examples and src subdirectories.
Man pages are a deliberate choice for a C library. They live on the system, they are searchable from the shell, they are versioned with the package, and they can be read over a terminal on a machine with no network. For a library with a stable API, a manual that is installed with the code is also a manual that cannot drift away from it.
The second documentation artefact matters more than it sounds. There is an API-CHANGES.md file, and the readme explains its purpose: if you have developed an application using libzip, you can find out about API changes and how to adapt your code for them there. That is an admission that a twenty-year-old C library does change, and a promise that the changes are enumerated rather than discovered. A library that is going to be a long-term dependency needs both properties, and most libraries offer one or the other.
The rest of the contributor surface follows the same pattern. There is a CONTRIBUTING.md and a CODING.md to read first, an AUTHORS file, a THANKS file, a NEWS.md for the release notes and a TODO.md, plus a SECURITY.md and a .clang-format file for a consistent style.
Getting it: packages everywhere, source when you must
Installation is unremarkable, which is a compliment for a library that has been around since 2005.
Most Linux and other Unix distributions include libzip in their package distributions, where it is usually called libzip or libzip-dev. On macOS it is included in both Homebrew and Mac Ports. On Windows it is in vcpkg. A list of the available packages across distributions is on Repology, and the project publishes a packaging status badge from the same source.
For building and installing from source, the readme points at the INSTALL.md file in the repository rather than repeating the steps, which is the right call for a project with several build systems.
The build machinery in the repository supports that. There is a CMakeLists.txt, a cmake/ directory and a cmake-compat/ directory for older CMake, a libzip-config.cmake.in for the CMake package configuration, and a libzip.pc.in for the pkg-config file. Two consumer-facing configuration files means the library can be found by both of the mechanisms a C project actually uses, and config.h.in and zipconf.h.in hold the compile-time configuration and the public header template.
The continuous integration picture is broad for a small C library: a GitHub Actions build workflow, an AppVeyor build for Windows, a Coverity scan status, and a fuzzing status badge pointing at the oss-fuzz project. The fuzzing badge is the interesting one, because it means the library is continuously fuzzed by the infrastructure that Chromium's own fuzzing effort provides, which is the strongest available signal for a library that parses untrusted archives.
Who uses it, and why that matters for a parser of untrusted input
The user list is the strongest argument in the readme, and it is a list of projects that parse hostile input for a living.
Among the open source users are KDE, Chromium, ImageMagick and VeraCrypt. VeraCrypt is the one that raises the stakes, since it handles encrypted volumes, and ImageMagick handles images in formats supplied by strangers, which means a zip embedded in a document. Chromium opens zip archives as part of its extension and component model.
The commercial list includes Adobe's Lightroom and the Kobo eReader, which is a good signal for the licensing position. The readme states that the BSD licence used for libzip allows its use in commercial products, and shipping a desktop application and an e-reader with the same dependency is a reasonable stress test for a licence claim.
There are bindings for other languages as well, for Python, Ruby through the zipruby gem, Lua and PHP, and others, and the project keeps a more complete list of projects using it on its site. A binding ecosystem is worth something beyond convenience, because it means the library is used by people who cannot patch the C, and a bug fixed once is fixed for all of them.
The in-tree infrastructure matches the user list. There is an ossfuzz/ directory, which is where the fuzzing harness lives, and a regress/ directory for the regression tests, alongside the examples and the man pages.
Where libzip is the wrong choice
The first limit is the format. This is a zip library, and if the requirement is tar, 7z, rar or squashfs, it is the wrong library, and no amount of configuration will change that.
The second is the transaction model. The design presumes a whole archive in play: changes are staged, deletions are marked, and the file is written on close. For an archive larger than the available memory that is a problem, and the Zip64 support removes the format limit but not the memory one. A use case that writes a hundred gigabyte archive in a streaming fashion needs a different tool.
The third is the deletion semantics, which are a feature and a cost together. Because data is never physically removed, an archive that has had many entries deleted can be much larger than its logical contents, and the tool offers no way to compact it that the readme describes. A user who rewrites an archive frequently has to think about that.
The fourth is the API change burden. API-CHANGES.md is a good thing, and it is also an admission that an application written against an old version needs work to move forward. For a library with a twenty-year history in a language without modules or namespaces, that is unavoidable, and the file is the honest way to handle it.
The fifth is the encryption story. Supporting Winzip AES and legacy PKWARE means supporting two schemes, one of which is older and weaker, and a security review will want to know what the library does with each. The readme lists the support and does not discuss the strength of either scheme, so that question has to be answered elsewhere.
The last is small but real. The repository is described as BSD licensed in the readme, while the licence field GitHub records for the project is one it cannot classify, so the file in the repository is the authoritative copy and is worth reading before it goes into a commercial product.
Editorial conclusion
The library fits a C or C++ application that has to read and write zip archives and wants a stable API, sensible transaction semantics and a fuzzing and static analysis history behind it rather than a dozen years of accumulated patches. It does not fit a project that needs streaming writes for archives larger than memory, since the design presumes a whole archive in play, and it does not fit a team that needs a format other than zip. Before adopting it, read API-CHANGES.md for the version you are moving from, and note the licence wording, because the readme calls it the BSD licence while the repository's own licence field is one GitHub cannot classify, so the file in the repository is the one to read. Version 1.12.1 was published on 2026-10-14, one day before the last push.
Frequently asked questions
What is libzip?
A C library for reading, creating and modifying zip archives, continuously developed since 2005 and usable on Linux, macOS, Windows and many other systems. Its stated design criteria are a stable API without breaking backwards compatibility, never creating corrupt files even in case of errors, never deleting data, and being efficient.
How do I install libzip?
Most Unix distributions ship it as libzip or libzip-dev, macOS has it in both Homebrew and Mac Ports, and on Windows it is in vcpkg, with a full package list on Repology. Building and installing from source is described in the INSTALL.md file in the repository.
Which compression methods and encryption schemes does libzip support?
Deflate, bzip2, LZMA and zstd compression, Zip64 for large archives, and both Winzip AES and legacy PKWARE encryption. Archives and file data can be read from files or from memory buffers, and unsaved changes can be reverted.
How do I find out what changed in the libzip API between versions?
The repository includes an API-CHANGES.md that describes the API changes and how to adapt your code to them. The library is also fully documented through man pages, with HTML versions on the project site and in the man directory, and libzip(3) lists all the others.
Which projects use libzip?
Among the open source users are KDE, Chromium, ImageMagick and VeraCrypt, and the commercial products named include Adobe Lightroom and the Kobo eReader. There are also bindings for Python, Ruby, Lua and PHP, and the project keeps a fuller list on its website.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nih-at-libzip)Was this useful?