Guava's real contracts: compatibility outside @Beta, and no guarantees for serialized objects
GitHub describes it as Google core libraries for Java. The repository metadata lists Java as its primary language. The metadata lists the Apache-2.0 license. This article stays within the project description and details documented in the GitHub repository README.
At a glance
- What is it?
- Guava is Google's Apache 2.0 licensed core Java library, published as com.google.guava:guava in a JDK 1.8 or higher JRE flavor and a separate Android flavor. Its own warnings page is the most useful thing in the repository, because it says plainly what Guava will not do for you.
- Who is it for?
- Guava is a good default for internal Java code, especially where you need collection types the JDK does not offer, and its compatibility promise outside @Beta is stronger than most libraries of its age. Two decisions have to be made explicitly rather than by default.
- 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?
- Yes. The repository last received commits 1 day 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 September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Serialized Guava objects are not a persistence format, and the project says so
One line in the warnings section decides whether Guava belongs in your storage layer. Serialized forms of ALL objects are subject to change unless noted otherwise, and the instruction that follows is not to persist these and assume they can be read by a future version of the library. That rules out more than people expect. It rules out caching an ImmutableList in a database column, putting an ImmutableMap into a message queue payload, writing one to a session store, or keeping one in a snapshot file next to your configuration. It is a different promise from the class of binary compatibility discussed later, and it is the one that fails silently: the write succeeds, the read throws, and the data is already gone. Guava's immutability and equality semantics are attractive for stored structures precisely because they look durable, and that instinct is what this warning is aimed at. Pick a serialization format you own, and treat any Guava object in your code as in-process only.
Guava collections are not hardened against a caller you do not trust
The fifth warning is short and easy to skim past. Guava's classes are not designed to protect against a malicious caller, and they should not be used for communication between trusted and untrusted code. The practical reading is about boundaries rather than about threads. If a value comes from a plugin, a tenant, a deserialized request, a sandboxed extension, or any other party that could hand you something hostile, do not put it into a Guava collection and assume the collection validates what goes in. A cache, a multimap, or a set built from untrusted input is a structure you are trusting, not one that is defending you. This is a normal division of labour in a library optimized for speed and clarity, and it is also the reason Guava does not advertise itself as a security boundary. Inside one process, among code you control, that trade is the right one. Across a trust boundary, the receiving side has to parse and validate before anything reaches a Guava type.
@Beta can be changed or removed in any release, and 21.0 was the last non-Beta removal
The compatibility story is precise enough to plan around. Anything marked @Beta at class or method level is subject to change and can be modified in any way or even removed at any time, which means a @Beta API gives you no timeline at all. Anything without @Beta is promised to remain binary-compatible for the indefinite future, and even @Deprecated APIs will stay unless they are also @Beta. The project is honest that this used to be different, since non-Beta APIs were sometimes removed after a deprecation period, and it names the last release where that happened: Guava 21.0. It adds that there are no plans to start removing things again while leaving the option open for something like a serious security problem. If your own code is a library on someone else's classpath, the warnings are directed at you specifically: do not use beta APIs unless you repackage them, and the Guava Beta Checker exists to catch that before it ships.
The dependency snippets still say 33.7.1 while the newest release is 33.7.2
Copying the build snippet gets you the previous patch release. Both examples on the page pin 33.7.1 with a flavor suffix, in Maven:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.7.1-jre</version>
<!-- or, for Android: -->
<version>33.7.1-android</version>
</dependency>and in Gradle:
dependencies {
// Pick one:
// 1. Use Guava in your implementation only:
implementation("com.google.guava:guava:33.7.1-jre")
// 2. Use Guava types in your public API:
api("com.google.guava:guava:33.7.1-jre")
// 3. Android - Use Guava in your implementation only:
implementation("com.google.guava:guava:33.7.1-android")
// 4. Android - Use Guava types in your public API:
api("com.google.guava:guava:33.7.1-android")
}The current release is 33.7.2, published on the same day as the last push, so the page trails its own tags by one patch. Two details in the snippet matter more than the patch number. The JRE flavor requires JDK 1.8 or higher, which is the floor your build has to clear, and the choice between implementation and api decides whether Guava types leak into your published signatures and whether every downstream consumer is dragged onto your version.
implementation versus api is the decision that outlives the version you pick
The four Gradle options are not four flavors, they are two decisions multiplied by two platforms. The platform is the -jre or -android suffix, and picking Android flavor is also the documented route for any library that wants to stay Android compatible even when it is not an Android app, since the Android source sits in the android directory of the repository. The scope is implementation against api. With implementation, Guava is a private implementation detail and your own public signatures cannot mention its types, which keeps consumers free to pick their own version. With api, Guava types become part of your contract, which is correct when callers need to pass an ImmutableList into your method and unavoidable coupling when they do not. A library that starts on implementation and later exposes a Guava type has changed its dependency contract, and the fix is a major version for your consumers, not a small one.
Snapshots use a deliberately impossible version and change under you
Nightly builds from master are published under a version that cannot collide with a release, 999.0.0-HEAD-jre-SNAPSHOT, with 999.0.0-HEAD-android-SNAPSHOT for the Android flavor. The choice of 999 is the useful part: because it is out of range for any real release, a snapshot dependency can never be confused with a pinned one, and a repository that mixes both stays resolvable. Alongside them the project publishes snapshot Javadoc and, more usefully, snapshot API diffs, so you can see what a given master build changed in the public surface before you adopt it. What you do not get is any promise of stability. Nothing pins the content behind 999.0.0-HEAD, so a build that resolves the snapshot can pick up different bytecode on a different day without a version change on your side. The documentation links for both the Javadoc and the diffs are under a snapshot-jre path, so the Android flavor's equivalent is not offered at the same location.
A BOM, a GWT module, ProGuard rules and a cycle suppress list ship without being in the README
The top level of the repository is more informative than the page describing it. Alongside guava/, the Android source, guava-tests/, guava-testlib/, integration-tests/, futures/, and util/, there is a guava-bom/ module, a guava-gwt/ module, a proguard/ directory, and a cycle_suppress_list.txt, plus a Maven wrapper in mvnw and mvnw.cmd with its .mvn/ configuration. None of these four appears in the build instructions. The BOM is the one with the largest practical effect, because it is how a multi-module build aligns one Guava version across every module instead of pinning it in each. The ProGuard directory means shrinker rules travel with the library rather than being something you write. The cycle suppress list is the one to know about before you add your own static checks, since it records dependency cycles the build tolerates on purpose, and a tool that forbids cycles will trip over entries that are deliberate. The GWT module has no explanation on the page at all.
com.google.common.io is only tested on Linux and Windows, and Android stops at API level 24
The sixth warning narrows the testing matrix in a way that changes where you verify. For the mainline flavor, the libraries are tested across a range of OpenJDK versions on Linux and Windows, and some features, especially in com.google.common.io, may not work correctly in non-Linux environments. The file utilities are where the risk concentrates, so anything you build on top of them needs its own check on the operating system you actually ship to, rather than an assumption inherited from a green build on a developer's laptop. For the Android flavor the unit tests also run on API level 24, Nougat, which is a floor rather than a claim about newer releases. The two flavors are also built from different source trees, so a behaviour you confirm on the JRE artifact is not automatically a behaviour of the Android artifact. Combined with the one runtime linkage dependency, com.google.guava:failureaccess:1.0.3, plus annotation-only dependencies, the practical picture is a library with a deliberately narrow set of promises, and the warnings section is where those promises are actually written down.
Editorial conclusion
Guava is a good default for internal Java code, especially where you need collection types the JDK does not offer, and its compatibility promise outside @Beta is stronger than most libraries of its age. Two decisions have to be made explicitly rather than by default. First, never persist a Guava object: serialized forms of all objects are subject to change, so a database column or a queue message holding one will not survive an upgrade. Second, never pass one across a trust boundary, because the classes are not designed to protect against a malicious caller. Before you bump the version, remember that the dependency snippets in the README still show 33.7.1 while the current release is 33.7.2, and if you publish a library, run the Guava Beta Checker so a @Beta dependency does not reach your users' classpath.
Frequently asked questions
What are the benefits of eating guava?
That is a question about the fruit. Guava the software project is Google's set of core Java libraries under the Apache 2.0 license, published as com.google.guava:guava in a JRE flavor that requires JDK 1.8 or higher and a separate Android flavor, adding collection types such as multimap and multiset, immutable collections, a graph library, and utilities for concurrency, I/O, hashing, primitives, and strings.
how to use guava leaves
Leaves are a plant question and nothing in this repository addresses it. For the Java library, use is a matter of declaring the dependency, with groupId com.google.guava and artifactId guava, a version suffixed -jre or -android, and either implementation or api in Gradle depending on whether Guava types appear in your public signatures.
how to set up guava lotus crib
A guava lotus is a different product and this repository has nothing to do with it. If you meant the library, its own build instructions cover only the Maven and Gradle dependency declarations, and it links a wiki page on using Guava in your build plus a separate page for the Android flavor.
Why does my stomach hurt after eating guava?
The repository contains no health guidance. The documented limits of the library are different ones: its classes are not designed to protect against a malicious caller and should not carry communication between trusted and untrusted code, and serialized forms of all objects are subject to change unless noted otherwise.
how to use guava paste
Guava paste is a food product and unrelated to this project. The library's equivalents are its text, primitives, hashing, and I/O utilities, with com.google.common.io called out specifically in the platform testing notes as the area that may not behave correctly outside Linux and Windows.
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/google-guava)