zip4j: the Java zip library that fills in what java.util.zip leaves out
A Java library for zip files and streams
At a glance
- What is it?
- A long-lived Java library whose whole argument is that the standard library handles streams but not archives, encryption, split zips or Zip64. The author restarted it years after the first release stalled.
- Who is it for?
- zip4j earns its place when you need archive-level operations rather than stream plumbing: AES encrypted zips, split archives, Zip64 offsets or a progress callback you can put on a UI. Its API is a single fluent entry point, and the dependency surface is a single Apache-2.0 artifact on Maven Central.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 7 months ago.
- What is it written in?
- Mainly Java, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An archive library built around the gap in java.util.zip
The pitch in the About section is blunt about what is missing from the platform. Zip4j is described as the most comprehensive Java library for zip files or streams, and at the time of writing the only one with zip encryption support. The author is explicit that this is not a rejection of the built-in code: the library depends on Java's own zip implementation for compression, and he credits the JDK for the hard part of writing the format correctly.
What the built-in code does not give you is archive-level manipulation. `java.util.zip` hands you streams, and everything above that, meaning walking entries, rewriting a header, moving a file into an existing archive or reporting progress, is your problem. The library's stated goal is to do that heavy lifting internally so application code does not deal with streams at all. The README makes the claim concrete by contrasting a single-line call against the boilerplate equivalent.
The Background section explains why this library has an unusual shape. It started in 2008 or 2009, was hosted as a zip file on the author's own website before GitHub was a default, then went quiet for years. The version numbers tell the same story: releases v2.11.4 and v2.11.5 landed in February 2023, three years apart, and then nothing until v2.11.6 in February 2026. The project is not abandoned, but it moves in bursts rather than on a schedule.
What the feature list actually commits to
The Features section is nine bullets and each one maps to a concrete API surface rather than a vague promise. Create, add, extract, update and remove all operate on an archive, which is the distinction that matters against the stream classes. Streams are supported in both directions through ZipInputStream and ZipOutputStream equivalents. Password protection is covered for both files and streams, in AES and in the older zip standard scheme. Zip64 is supported, which is what you need once an archive passes the point where the original 32-bit offsets stop working.
Compression is a choice rather than a fixed behaviour. Deflate is the default, and STORE is available for the cases where you want entries stored without compression, which matters for already-compressed payloads and for archives you intend to serve over a network that is compressing again. Split archives are supported in both directions, using the numbered segment convention of z01, z02 and a final .zip.
Two entries in that list have no equivalent anywhere else in the Java ecosystem, and they are the ones that decide whether you need this dependency. Zip encryption is the first. The second is the progress monitor, which the README describes as existing for integration into apps and user-facing applications. A progress monitor means a callback you can wire to a progress bar, and that is the feature that turns a blocking library call into something you can run against a visible UI without freezing it. The topics on the repository, java-zip, split-zip, zip-encryption and zip4j, point at the same two features.
One entry point, and parameters for the variations
Adding a single file is one line, and the path can be a string or a `File`:
new ZipFile("filename.zip").addFile("filename.ext");Multiple files take a list, and a directory takes a `File` pointing at it:
new ZipFile("filename.zip").addFiles(Arrays.asList(new File("first_file"), new File("second_file")));Everything that varies between calls is carried by a `ZipParameters` object rather than by extra methods. Streams, for instance, need parameters passed in, and passing a fresh `new ZipParameters()` gets you the defaults:
new ZipFile("filename.zip").addStream(inputStream, new ZipParameters());Choosing STORE instead of Deflate is the same shape, one setter on the same object. That the README documents compression this way rather than as a separate method says something about the design: `ZipFile` is the whole public surface, and the parameter object is where every variation lives. Excluding files when adding a folder works the same way, through a filter handed to the parameters object since version 2.6. One consequence worth noting is that reading the README tells you how to configure a call but not what the defaults are, because those live in the `ZipParameters` javadoc rather than in the README.
The JDK version story does not resolve cleanly
The Requirements section states JDK 7 or later, and then a footnote undercuts the headline. Zip4j is written on JDK 8 because some of the NIO features it supports need JDK 8, but it keeps a JDK 7 path because it is widely used on Android and older Android versions need to keep working. When a JDK 8 feature or class is missing, the library falls back to the JDK 7 equivalent, and the footnote states plainly that on JDK 7 not all features will be supported.
Both facts are real and they point in different directions. The stated requirement is 7, and the stated cost of meeting it is a reduced feature set. Meanwhile the newest release notes for v2.11.6 list a bump of minimum JDK versions to 8 as an improvement. So the README's floor and the shipped artifact's floor are not the same number, and the repository does not explain which one a current user should plan around.
There is a second version signal worth separating. The README's Maven block names 2.11.6 as the version to depend on, and that matches the newest release. This is the rare case where the documentation and the release history agree, so a reader can copy the coordinates from the README without checking Maven Central for the current number. The artifact coordinates themselves are ordinary: group `net.lingala.zip4j`, artifact `zip4j`, licensed Apache-2.0.
A small repository with a Maven build and an Android pipeline
The tree is short, which fits a library rather than an application: `.github/`, `.gitignore`, `LICENSE`, `NOTICE`, `README.md`, `pom.xml`, `src/` and a single shell script named `trigger-android-build.sh`. There is no `examples/` directory and no separate documentation site in the tree, so the README and the javadoc hosted on javadoc.io are the whole documentation surface.
Two build systems are visible in that one line. `pom.xml` is the Maven build that produces the artifact on Maven Central. The Android script points at a separate verification path, and the badges confirm it as a distinct concern: a GitHub Actions workflow for the Maven build and a CircleCI badge labelled for Android tests. That split matters for judging maintenance, because a library used on Android carries obligations that a plain server-side dependency does not, and it explains why the project is careful about the JDK 7 fallback discussed above.
The release notes are terse issue references rather than prose. v2.11.6 adds the ability to create a split zip file from a stream and bumps a couple of dependency versions. v2.11.5 and v2.11.4, both from February 2023, are two bug fixes each: one allowing empty files to be overridden even when the target is not a zip file, and one swapping `toPath` for `getPath` to avoid a dependency on NIO plus treating a symlink as a file even when it points at a directory. Those are the kinds of fixes that only appear when people are using the library against real archives, which is a better signal than a feature count.
Where this sits against the platform and other libraries
The honest comparison is against two alternatives, and Zip4j wins only one of them clearly. Against `java.util.zip` the argument holds, because the platform gives you streams and no archive manipulation, and the encryption gap was real when the library started. Against newer platform APIs the margin is thinner. The JDK has grown over the years, and a reader evaluating this today should check what the current JDK offers before assuming the gap is as wide as the README describes.
What the README does not offer is a feature comparison table, benchmark numbers or any statement about which other libraries it replaces. There is no discussion of Commons Compress anywhere in it. That absence matters if you are choosing between libraries, because Commons Compress is the other Java option people arrive at, and Zip4j makes no attempt to explain why you would pick it instead. The choice reduces to priorities: archive-level operations and progress reporting pull toward Zip4j, broad format coverage pulls toward Commons Compress.
The maintenance question is the one to settle before adopting. This is a library with 2227 stars, 325 forks and 86 open issues, last pushed on 2026-03-11, with a release from 2026-02-12 that closed an issue from 2023. That pattern reads as a project in steady maintenance with bursts of work, not as one that will respond quickly to a new report. For a library whose failure mode is a corrupt or unreadable archive rather than a crash, that is an acceptable trade, but it is a decision rather than an oversight.
Editorial conclusion
zip4j earns its place when you need archive-level operations rather than stream plumbing: AES encrypted zips, split archives, Zip64 offsets or a progress callback you can put on a UI. Its API is a single fluent entry point, and the dependency surface is a single Apache-2.0 artifact on Maven Central. The thing to weigh first is cadence. The last push to master was 2026-03-11, while the newest release, v2.11.6, shipped 2026-02-12, so the library is stable rather than busy. Pin the version, read the JDK 7 fallback note before you assume full feature coverage, and treat the progress monitor as the reason to adopt it rather than the encryption, which the standard library now partly covers.
Frequently asked questions
How do I create a zip file in Java?
With zip4j it is one call: `new ZipFile("filename.zip").addFile("filename.ext")`. The JDK's own zip classes work at the stream level, so you handle entries yourself; zip4j handles the archive.
Which Java versions does zip4j support?
The README states JDK 7 or later, and notes the library is written on JDK 8 with a fallback to JDK 7 features, on which not all features work. The v2.11.6 notes also list a bump of the minimum JDK to 8.
Does zip4j support password protected and encrypted archives?
Yes. The feature list covers reading and writing password protected zips and streams in both AES and the older zip standard encryption, and the project describes itself as the only Java library with zip encryption support.
What does the progress monitor in zip4j do?
It is a callback for reporting progress, which the README says exists for integration into apps and user facing applications. It is the feature to reach for when a zip operation runs long enough to need a progress bar.
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/srikanth-lingala-zip4j)