jackson-core: the streaming layer underneath Jackson databind
Core part of Jackson that defines Streaming API as well as basic shared abstractions
At a glance
- What is it?
- The base package of the Jackson stack, defining the parser and generator abstractions that databind and every alternate data format build on, plus the processing limits added in 2.15 and 2.16.
- Who is it for?
- jackson-core is a library you adopt through databind rather than directly, and it earns its place by keeping the streaming layer format independent while leaving JSON specific code in the packages named for it. Reach for the API directly when you need to stream a document you will never bind to a class, when you want the resource caps configured on the factory, or when you are writing another format module.
- 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
Abstractions that are not JSON specific, despite the names
The first thing the README says is also the most useful thing it says. The core abstractions are not JSON specific, even though the word JSON appears in many class names for historical reasons, and only the packages that specifically contain the word json are JSON specific. That distinction is not cosmetic. It is the reason Smile, XML, CSV, YAML, Protobuf and CBOR can all be implemented on the same base package and still work with the standard databind package, so the format you choose at the factory level does not change the binding API your code calls.
The stack has two layers. jackson-core is the low level, incremental parser and generator layer. jackson-databind is the data binding layer that builds on top of it. If you have ever called `ObjectMapper.writeValueAsString`, you have used databind, which means jackson-core was already on your classpath.
The repository metadata is consistent with that positioning: Java, Apache 2.0 licensed, default branch `3.x`, last push on 2026-09-25, and topics limited to jackson, json and hacktoberfest. The repository has no GitHub releases, so version history comes from the README and the `release-notes/` directory rather than a release feed. The tree also holds `CLAUDE.md`, `SECURITY.md`, `create-test-report.sh` and `release.sh`, which tells you the project expects contributions from coding agents and has a script for cutting a version.
Two package names for two major versions
Adding the dependency means picking a major line, because the Java package name changed. Jackson 3.x lives in `tools.jackson.core` and Jackson 2.x in `com.fasterxml.jackson.core`:
<dependency> <!-- Jackson 3.x -->
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>3.2.3</version>
</dependency>
<dependency> <!-- Jackson 2.x -->
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.21.5</version>
</dependency>Same artifact name, same conceptual API, different import paths. If you are migrating a codebase from 2.x to 3.x, this is the change you hit first in nearly every file.
The README states the package has no external dependencies except for testing, where it uses JUnit. That is worth taking at face value and also worth noting for what it implies: if your dependency tree already carries jackson-core, nothing else arrived with it.
Beyond Maven, the jar works in two module systems without modification. It is a functional OSGi bundle with proper import and export declarations, so it drops onto an OSGi container as is. Jackson 2.10 and above ship `module-info.class`, which makes the jar a proper JPMS module, and Jackson 2.12 and above add Gradle 6 module metadata for version alignment. Non-Maven users download the jar from the Central repository.
JsonFactory, then a parser or a generator
Usage starts from a factory, and the README calls the important property out in its first sentence: the factory should be reusable, and once configured it is thread safe. That is the whole configuration model, one object created at startup and shared.
// Builder-style since 2.10:
JsonFactory factory = JsonFactory.builder()
// configure, if necessary:
.enable(JsonReadFeature.ALLOW_JAVA_COMMENTS)
.build();If you already have an `ObjectMapper` from databind, there is no need to build a factory yourself:
JsonFactory factory = objectMapper.tokenStreamFactory();From there, reading is `JsonParser` and writing is `JsonGenerator`, with subclasses for the non-JSON formats. The README deliberately does not inline an example of either loop, pointing instead to a blog post on reading and writing event streams for the shape of the cursor. That is a reasonable choice for a base package, since the useful part is the pull model: you advance through tokens instead of materialising an object graph, which is what lets a huge log file be processed in bounded memory.
One behaviour to understand before you enable features by reflex. `JsonReadFeature.ALLOW_JAVA_COMMENTS` in that snippet is not a compatibility gesture, it is a decision about what input you will accept. Every read feature you turn on widens what the parser tolerates, and for input arriving from another process that tolerance is a risk rather than a convenience.
StreamReadConstraints and the resource caps added since 2.15
Starting with Jackson 2.15, jackson-core carries configurable limits on input decoding and output generation. The README is careful about what those limits are and are not, which is the part most people skip. Limits are expressed in input or output units, bytes or characters, depending on the source. They are defined as the longest allowed length but are not imposed at exact accuracy, so a configured maximum of 1000 units might not reject something of length 1003 while 1500 typically does. They live in `StreamReadConstraints` and `StreamWriteConstraints`, and they are configurable per `JsonFactory`.
The stated purpose is not validation. It is reducing the likelihood of excessive memory usage, excessive retention, or excessive processing cost. That framing matters when you choose the numbers.
The defaults are worth reading closely, because they changed between major versions:
* Maximum Number token length, since 2.15: 1000 for both integral and floating point numbers. * Maximum String value length, since 2.15: 100,000,000 since 3.1, and 20 million in 2.x and 3.0. * Maximum input nesting depth, since 2.15: 500 levels in 3.x, and 1000 levels in 2.x. * Maximum property name length, since 2.16: 50,000. * Maximum document length, since 2.16: unlimited, expressed as -1. * Maximum output nesting depth, since 2.16.
So the cap that does the most work against a hostile payload is nesting depth, and it is also the one where 3.x is stricter than 2.x by default. A 100 million character string limit is not a defence; it is a ceiling that only pathological memory pressure will reach. If you parse JSON from other people, depth and number length are the two limits to lower deliberately.
Where jackson-core sits against Gson and the other formats
The honest comparison with Gson is about scope rather than speed. Gson reads and writes JSON into reflective Java types and is a single small library with a very small surface. jackson-core does not bind anything at all, so comparing the two directly compares a streaming cursor to an object mapper. The comparable question is what happens when you move up to databind: you get a factory you configure once, a feature system for what the parser accepts, format modules behind the same interfaces, and processing limits you can set per factory. The README makes no performance claims of any kind, so a speed comparison in that direction is not something this repository supports.
Against the other formats the argument is stronger, because that is where the abstraction pays. Smile is a binary JSON encoding, CBOR and Protobuf are binary schemas, and XML, YAML and CSV are text formats with their own awkward edges. All of them are separate modules implementing the interfaces defined here, and the README states the consequence directly: you can use the standard data binding package regardless of the underlying data format. Adding a format means implementing `JsonParser` and `JsonGenerator`, not learning a new binding API.
That is also the practical limit of the package as a standalone choice. If your application reads JSON into classes, you are a databind user and jackson-core is infrastructure. Choosing it directly means you want the event stream, which the README's own pointer to the event stream blog post confirms is the intended use.
What the README settles and what it hands off
The README is accurate about being an index rather than a manual. It states the project's position, gives coordinates for both major versions, shows factory creation in two forms, then lists the constraints with their defaults and the issue number each one came from. Several entries cite a specific jackson-core issue or pull request, which is unusually traceable for a table of defaults.
What it does not settle is the API surface itself. There is no javadoc walkthrough, no example of a parser loop, and no comparison table. The links go outward: Javadoc on javadoc.io, code coverage on codecov for the 3.x branch, an OpenSSF Scorecard entry, a Tidelift sponsorship link, the release notes directory, and the cowtowncoder blog post for the streaming example. Javadoc for a package this size is a long afternoon of reading, so plan for it.
Two build signals are worth noting if you are evaluating this as a dependency. CI runs from `.github/` with a build badge in the README's status table, and coverage is tracked per branch. That status table is also where the Maven Central version badge sits, which is the fastest way to confirm which line is actually shipping.
One naming trap when you read the tree: `3.x` is the default branch, and the 2.x line lives elsewhere in the FasterXML organisation. The two versions in the dependency block therefore come from different branches with different defaults, which is exactly why the constraint list reads differently depending on which one you depend on.
Editorial conclusion
jackson-core is a library you adopt through databind rather than directly, and it earns its place by keeping the streaming layer format independent while leaving JSON specific code in the packages named for it. Reach for the API directly when you need to stream a document you will never bind to a class, when you want the resource caps configured on the factory, or when you are writing another format module. Before adopting it, check which major line your project is on: the package name, the default nesting depth and the string length limit all differ between 2.x and 3.x, and the README gives the exact coordinates for both.
Frequently asked questions
What is jackson used for?
Jackson is used to read and write JSON in Java. jackson-core is its low level layer, providing incremental parser and generator abstractions, and jackson-databind is the layer most applications use, mapping JSON to and from Java objects.
What is the current version of jackson?
The README lists two current lines: Jackson 3.x at 3.2.3 under the groupId `tools.jackson.core`, and Jackson 2.x at 2.21.5 under `com.fasterxml.jackson.core`. The default branch of the repository is 3.x.
What is com fasterxml jackson core jackson databind?
They are two artifacts in the same stack, and the README describes the relationship directly: jackson-databind builds on jackson-core. Core handles the streaming parse and generate layer, databind adds object mapping on top of it. In Jackson 3.x the package moved to `tools.jackson.core`.
Is jackson faster than Gson?
The README makes no speed claims, so nothing here supports a benchmark comparison. What it documents is scope: jackson-core is a streaming layer with no binding at all, and the feature and limits surface lives on a shared `JsonFactory` rather than on the parser class.
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/fasterxml-jackson-core)