JJWT: a JOSE library for Java that takes algorithm coverage seriously
Java JWT: JSON Web Token for Java and Android
At a glance
- What is it?
- Eleven thousand stars, Apache 2.0, and tables listing every JWS, JWE and key management algorithm by identifier. The design decisions worth reading about are in the module layout and the release notes.
- Who is it for?
- JJWT is the rare security library where the feature list is a specification inventory, and that cuts both ways. You get every standard algorithm, native Java `Key` types for JWK handling, and a parser that refuses algorithms you did not configure, which is the failure mode that matters most in token verification.
- 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 18 days 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 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The README is a specification inventory
The stated aim is to be the easiest library to use and understand for creating and verifying JSON Web Tokens and JSON Web Keys on the JVM and Android, and the implementation is pure Java built exclusively on the JOSE working group specifications. Eight RFCs are listed by number: 7519 for JWT, 7515 for JWS, 7516 for JWE, 7517 for JWK, 7518 for JWA, plus 7638 for key thumbprint, 9278 for thumbprint URI, 7797 for the unencoded payload option, and 8037 for Edwards curve algorithms.
Most of the README is then four tables. The first lists eleven signature algorithms with their identifier and description, from `HS256` through `RS512`, `PS256` to `PS512` and `EdDSA`. The second lists six authenticated encryption algorithms for JWE. The third lists seventeen key management algorithms, including `RSA1_5`, the three AES key wrap variants, the four `ECDH-ES` family members, the two GCM key wrap options, and three PBES2 options with SHA-256, SHA-384 and SHA-512. The fourth maps JWK formats to native Java key types and JJWT types, pairing `SecretKey` with `SecretJwk`, RSA keys with `RsaPublicJwk` and `RsaPrivateJwk`, and the XDH and EdDSA keys with the octet JWK types.
That last table is the one to read for API design. The library does not hide keys behind its own container type; it works with `SecretKey`, `RSAPrivateKey` and the rest, so existing key management code interoperates without translation.
Java version requirements are annotated per algorithm, not blanket
The algorithm tables carry footnotes, and those footnotes carry the real compatibility story. `PS256`, `PS384` and `PS512` are marked as requiring Java 11 or a compatible JCA provider such as BouncyCastle in the runtime classpath. `EdDSA` is marked as requiring Java 15 or a compatible provider. The same two footnotes reappear on the JWK table for `XECPublicKey` and `EdECPublicKey`.
This is a nicer way to express the problem than a single minimum version. RSA-PSS needs a newer JCA, EdDSA needs a much newer one, and a project on Java 11 that only needs HMAC signing should not be told it cannot use the library.
The feature list, though, states that the library is fully functional on all Java 8 and later JDKs and on Android. That sits slightly oddly next to the 0.13.0 release notes, which say that Java 8 compatible changes will land in the next minor release, 0.14.0. Both statements can be read as true under different readings of what the Java 8 baseline covers, and the footnotes are the more precise guidance: check the JCA version for the specific algorithm you need rather than assuming.
api, impl, extensions and a BOM in the module layout
The tree shows a Maven multi-module layout with `api/`, `impl/`, `extensions/`, `bom/` and `tdjar/`, alongside `src/` for documentation sources, a `pom.xml`, a `mvnw` wrapper and `install-test-jdks.sh`. The separation of `api` from `impl` is the classic Java library pattern, and it is the one that matters for dependency hygiene: the search terms people use for this project include `jjwt-api` and `jjwt-jackson` as separate coordinates, which is exactly what that split produces.
The `bom/` module is newer. Release 0.12.7, published 2025-08-14, added a Maven BOM, described as useful for multi-module projects. For a library with this many coordinates, a BOM is the difference between pinning four versions consistently and hoping.
The coverage claim deserves attention because it is unusual. The README states almost 1,700 tests with enforced 100 percent test code coverage, where every method, statement and conditional branch variant is required to pass on every build, and that implemented functionality is verified against RFC-specified test vectors. Running coverage as a build gate rather than a report is what makes the claim mean something, and the presence of a Coveralls badge plus a Snyk vulnerability badge in the header is how you would know whether it is being enforced.
Parser hardening shows up in patch release notes
The 0.12.7 notes are a better guide to how the project is maintained than any amount of feature description. Alongside the BOM, they allow the `JwtParserBuilder` to have empty nested algorithm collections, which effectively disables the parser's associated feature.
Read carefully, that is a security-motivated change rather than a convenience one. A parser configured with an empty algorithm list does not fall back to a permissive default; it refuses to verify with that family of algorithms. That is the difference between a parser that fails closed when misconfigured and one that quietly accepts whatever the token asks for.
Version 0.13.0 followed six days later on 2025-08-20 and contains exactly one change: a previously private `JacksonDeserializer` constructor taking an `ObjectMapper` and a claim type map was made public, so callers can register a claims type converter against their own mapper. Small, specific, and the kind of change that only makes sense in a project where the API surface is curated deliberately.
Automatic assertions, and what they cost you
The feature list advertises automatic security best practices and assertions alongside fluent interfaces that work well with IDE autocompletion. The two claims pull in different directions and it is worth separating them.
The assertions are the part that can surprise you. A parser that fails on an expired token or on a token whose issuer does not match is doing something you might have expected to configure. Most JWT libraries give you a builder where you turn checks on; the claim here is that sensible defaults come for you.
The fluent interfaces are the ordinary Java story. `Jwts.builder()` style chains are readable in a way that the Jwt.Net equivalents are not, because JJWT has one entry point per operation rather than four collaborators you assemble yourself. For a developer writing token code rarely, that difference is real.
Neither claim tells you how to handle a key set that rotates, or where the JWK Set URI resolution happens, and those are the questions that decide whether this is a good fit for a service that accepts tokens from several issuers. Those live outside the README, in the reference documentation the project links.
Where the project stands and what it does not decide
At 11,136 stars and 1,394 forks, JJWT is the most established library in this article by an order of magnitude. It is Apache 2.0 licensed with both `LICENSE` and `NOTICE.md` in the tree, carries a `SECURITY.md`, and lists 22 topics covering the specification names rather than marketing terms, including `jwk`, `jwe`, `jws`, `jwk-thumbprint-uri` and `jwt-bearer-tokens`. That topic list is a reasonable summary of scope.
The last push recorded is 2026-09-18 and there are 44 open issues. The README is written in AsciiDoc rather than Markdown, with attribute-driven tip and note captions that render as callouts on GitHub, which is a small sign of how much care goes into the published output.
What the README does not do is tell you which algorithm to pick for a new system, how to load keys from a JWKS endpoint, or how to migrate from a version you are already on. Those are documentation site and upgrade guide questions. For a project of this maturity that division is reasonable, but it does mean the README alone is an advertisement for a much larger body of documentation.
Editorial conclusion
JJWT is the rare security library where the feature list is a specification inventory, and that cuts both ways. You get every standard algorithm, native Java `Key` types for JWK handling, and a parser that refuses algorithms you did not configure, which is the failure mode that matters most in token verification. The cost is a multi-module Maven dependency and a fluent API that takes a screenful to learn. Version 0.13.0, published 2025-08-20, is the last minor line supporting Java 7, and the notes state plainly that 0.14.0 and later require Java 8, so check your build's minimum before pinning a version. The repository's last push is 2026-09-18 and it is Apache 2.0 licensed with a `SECURITY.md` in the tree.
Frequently asked questions
What is JWT mainly used for?
A JWT is a signed, self-contained set of claims used to carry identity or authorization information between parties without a shared session store. JJWT creates and verifies them on the JVM and Android, and also handles JSON Web Keys so the signing material can be managed as first class objects.
What is the difference between JWT and JWK?
A JWT is the token itself: a header, a payload of claims and a signature. A JWK is the key, represented as a JSON object so it can be published and shared. JJWT covers both, and maps JWK formats onto native Java key types such as `SecretKey` and `RSAPrivateKey`.
Can you explain what a JWK is and what it is used for?
A JSON Web Key is a standard JSON representation of a cryptographic key, used to publish keys over HTTP so verifiers do not need out-of-band key distribution. JJWT creates, parses and verifies JWKs in all standard formats, including RSA, EC, XDH and EdDSA keys.
How can I decode a JWT token?
With JJWT you parse with a parser built from `JwtParserBuilder`, which can verify the signature and run the standard validity checks in the same call. The parser is configured with explicit algorithm collections, and empty collections disable that algorithm family rather than relaxing it.
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/jwtk-jjwt)