Library / SDK
vavr-io/vavr avatar
vavr-io/vavr

vavr: the Java library that made immutability the default argument

vʌvr (formerly called Javaslang) is a non-commercial, non-profit object-functional library that runs with Java 8+. It aims to reduce the lines of code and increase code quality.

6,179 stars682 forksJavaApache-2.0

At a glance

What is it?
Twelve years after starting as Javaslang, vavr shipped a 1.0.0 it calls a drop-in replacement for 0.11.0, then fixed a serialization bug three weeks later.
Who is it for?
vavr is a reasonable pick when a Java codebase is fighting nullability and exceptions rather than missing a data structure, because `Option`, `Try` and `Either` make failure part of a return type and the persistent collections remove the shared-mutable-state class of bug. The 1.0.0 release settles the long question of whether the API was going to keep moving, and its promise is stability rather than novelty.
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 October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Twelve years from Javaslang to a stable 1.0

The version history explains the shape of the project. The 1.0.0 release notes describe a library that started in 2014 as Javaslang, a small experiment in bringing functional programming to Java, and grew into something thousands of projects depend on. The 1.0.0 tag is called the first stable major release and is explicitly framed as a drop-in replacement for 0.11.0: the API you know is the API you get.

That framing is unusual and worth taking at face value rather than discounting as marketing. A library that renames or reshapes its core types at 1.0 would force every caller to change. vavr chose the opposite and said so directly, with the useful qualifier that the goal was to formalize stability that 0.x users had relied on for years rather than to reinvent anything.

The release line then moved quickly. v0.11.0 shipped on 2025-12-14, the first minor release in several years, and said the 0.11.x line would keep receiving fixes with no new features planned. v1.0.0 followed on 2026-02-09, and v1.0.1 on 2026-03-01. GitHub reports 6,173 stars, 679 forks and 100 open issues, and the last push was on 2026-09-19, so this is an actively developed codebase rather than an abandoned experiment.

What the library gives a Java developer

The README lists four things: persistent collections, functional abstractions for error handling and concurrent programming, pattern matching, and more. The single most useful claim is the constraint underneath them: vavr has no dependencies beyond the JVM, so it can be added as a standalone jar.

The persistent collections are the part with the clearest engineering payoff. A persistent data structure shares structure with its predecessors, so adding an element returns a new collection without copying the whole thing and without mutating the old one. In practice that removes an entire family of aliasing bugs, and it is the reason a vavr collection can be passed across threads without defensive copying.

The error handling types are the other reason teams adopt it. `Option` represents a value that may be absent, `Try` represents a computation that may fail with an exception, and `Either` carries a typed error. The point is not that exceptions are bad but that the failure case becomes visible in the method signature, which a compiler and a reader can both see. Pattern matching and lazy for-comprehensions cover the third case, where a chain of operations is written once instead of nested.

The repository topics confirm the shape: functional-programming, immutable-collections, persistent-collections, object-functional, java, javaslang and hacktoberfest.

Adding the dependency

The README gives a Maven coordinate and a Gradle coordinate, both at 1.0.1, which matches the most recent release tag. Nothing else is needed, since there are no transitive dependencies to audit.

xml
<dependency>
    <groupId>io.vavr</groupId>
    <artifactId>vavr</artifactId>
    <version>1.0.1</version>
</dependency>

The Gradle form is the usual single line, which is convenient in a version catalog or a platform-wide dependency constraint:

groovy
implementation 'io.vavr:vavr:1.0.1'

The README also points at javadoc.io for the API documentation and at docs.vavr.io for a user guide. That distinction matters more here than in most libraries, because a collection library has a large surface and the guide is where the design intent lives, while the javadoc is where the signatures live.

The badges tell the same story from another angle: Maven Central versions are listed with a version prefix of 1, and the javadoc badge resolves to 1.0.1.

The bug 1.0.1 fixed, and why it was not obvious

The 1.0.1 release exists for one reason: a native serialization bug in `HashMap` that serialized the internal `HashArrayMappedTrie` structure including the pre-computed hash values of keys. For keys such as enums that rely on `Object.hashCode()`, those stored hash values differ across JVM restarts, so lookups fail in a different process than the one that wrote the data.

That failure mode is worth understanding regardless of whether you upgrade, because the symptom is a map that looks populated and returns nothing. It only appears across a serialization boundary, and only for key types whose hash is not stable between runs, so it would not show up in a single-process test suite.

It is also a reasonable argument for taking 1.0.1 rather than 1.0.0. A library that declares a stable 1.0 and then fixes a native-serialization defect three weeks later is behaving the way a mature library behaves, and the release note documents the mechanism in enough detail to let a reader confirm the diagnosis themselves.

Two places where the README lags the releases

The contributing section describes two significant branches: `main`, which represents a stream of work leading to the release of a new major version, and `version/1.x`, which holds historical work that went into `1.0.0-alpha-3` and is treated as read-only, kept around for cherry-picking. Both statements are accurate about intent and both predate what actually shipped. Version 1.0.0 and 1.0.1 are already published, so `main` is no longer waiting on a major version, and the read-only branch is described in terms of an alpha that the stable line superseded.

The same kind of drift appears in the Java version. The repository description says the library runs with Java 8 and later, and the README says it is an extension for Java. The v0.11.0 release notes, however, point at a significant Java version bump as part of the move toward 1.0.0. Those two claims are in tension, and the resolution a reader needs is not in the README at all: it is in the `pom.xml` and the build configuration in the repository tree, where the compiler target actually lives. If you are on an older JDK and care about compatibility, read the pom rather than trusting the description field.

Neither issue is a reason to avoid the library. Both are reasons to read the build file rather than the marketing text, which is ordinary practice for a project of this age.

Working on the library itself

The README notes that a small number of users have reported problems building vavr and points them at `CONTRIBUTING.md` for details, and the repository tree carries a Maven wrapper, so a local build does not need a system Maven. The tree is small and conventional: `pom.xml`, `mvnw`, `mvnw.cmd`, a `.mvn/` directory and the `vavr/` module directory.

The useful Maven goals are listed in the README, and the coverage and javadoc ones are the two a contributor reaches for first.

bash
mvn clean test
mvn -P ci clean test jacoco:report
mvn javadoc:jar

That the project documents its own build friction is a small positive sign. A library at 1.0 with twelve years of history and 100 open issues is not going to have an empty tracker, and a repository that names the known problem and links to the fix path is easier to contribute to than one that does not.

Editorial conclusion

vavr is a reasonable pick when a Java codebase is fighting nullability and exceptions rather than missing a data structure, because `Option`, `Try` and `Either` make failure part of a return type and the persistent collections remove the shared-mutable-state class of bug. The 1.0.0 release settles the long question of whether the API was going to keep moving, and its promise is stability rather than novelty. The concrete things to check before adopting are the Java version floor, which the repository description and the release notes describe differently, and the branch layout, which the contributing section still describes in terms that predate the stable release. Start from the 1.0.1 coordinate block in the README, read the user guide at docs.vavr.io rather than the README, and pin the version explicitly.

Frequently asked questions

What is vavr and what does it add to Java?

vavr is an object-functional extension library for Java that supplies persistent collections, typed error handling through Option, Try and Either, and pattern matching. It has no dependencies beyond the JVM, so it can be added to a classpath as a single standalone jar.

Is vavr 1.0.0 a breaking change from 0.11.0?

The 1.0.0 release notes call it a drop-in replacement for 0.11.0 and state that the API you know is the API you get. The release deliberately formalized existing stability rather than reshaping the library, and the javadoc badge plus the README coordinates both point at the current 1.0.1.

Which Java version does vavr require?

The repository description says Java 8 and later, while the 0.11.0 release notes point at a significant Java version bump as part of the move toward 1.0.0. The two statements disagree, so the authoritative answer is the compiler target in the pom.xml in the repository tree.

What bug did vavr 1.0.1 fix?

It fixed a native serialization bug in HashMap that wrote the internal HashArrayMappedTrie structure including pre-computed key hash values. For key types such as enums that depend on Object.hashCode(), those values differ across JVM restarts, so lookups failed after deserialization in another process.

Why is vavr sometimes called Javaslang?

Javaslang was the library's original name, and the project started under that name in 2014 as an experiment in functional programming for Java. The rename to vavr happened as the library grew, and the repository still carries javaslang among its topics.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. vavr-io/vavr on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/vavr-io-vavr.svg)](https://hysenlabs.com/projects/vavr-io-vavr)