Open-source project
FasterXML/jackson-annotations avatar
FasterXML/jackson-annotations

jackson-annotations: the mapping vocabulary without the mapping engine

Core annotations (annotations that only depend on jackson-core) for Jackson data processor

1,071 stars347 forksJavaApache-2.0

At a glance

What is it?
FasterXML/jackson-annotations is a small Java module holding the annotation types that Jackson's data processor reads, while the code that actually interprets them lives in jackson-databind. This review covers the module boundary, the version numbering that dropped patch numbers, mix-in and inheritance precedence, and the cases where annotations are the wrong tool.
Who is it for?
Adopt jackson-annotations when your Java project already runs Jackson and you want JSON property names, ignore rules, type narrowing or creator binding declared on the type rather than scattered through configuration. Do not reach for it expecting serialization to work on its own, because every behaviour it names is implemented by jackson-databind, and skip the module entirely if you need annotations that require databind since those are not shipped here.
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 2 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 November 6, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • FasterXML/jackson-annotations1,071 ★ · -1
Star history
Repository2026-10-202026-11-06
FasterXML/jackson-annotations1.1k1.1k

-1 Stars in the last 17 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The module that ships annotations without behaviour

jackson-annotations contains annotation types and their related value classes. It contains no functionality that uses annotations. The project description makes that limit explicit: the annotations included are the ones that depend only on jackson-core, and the ones left out are the ones that would require a dependency on the Databind package. Anything that interprets these annotations, such as inclusion rules, container content handling or Optional value processing, is implemented by jackson-databind instead. That is a deliberate design rather than an unfinished state, and it explains the module's small size. For a developer the practical consequence is straightforward: adding this dependency gives you a vocabulary, not a serializer. The type of every annotation is in the single Java package com.fasterxml.jackson.annotation, so a quick import scan tells you exactly what is on the table. The repository points to a Full Listing of Jackson Annotations wiki page for the complete set rather than enumerating them in the README.

Version numbers that dropped the patch component

Release notes for this component are not kept in the repository. They live on a unified Jackson Releases wiki page shared by all official Jackson components, and the repository itself has no GitHub releases. The version scheme changed at Jackson 2.20. Before that release the patch number was included but meaningless, because every patch version of a minor release was identical, so 2.18.0 and 2.18.4 were the same artifact. From 2.20 the module is released with a simple version such as 2.20, with a patch number only in the rare case of a critical fix. A second note covers the 3.x line: Jackson 3.x components rely on the 2.x annotations, and no separate 3.x jackson-annotations versions are released, since release candidates existed up to 3.0-rc5 but nothing after that. If you write dependency management rules against this module, those two notes are the ones to encode.

Mix-ins and the interface precedence rule

Jackson's annotations do a few things regular Java annotations do not. The first is mix-in annotations, which let you attach annotation definitions to third-party classes without modifying those classes. The second is full inheritance, so an annotation definition can be overridden, and that covers method and field annotations as well as class level ones. The third is inheritance from interfaces, and this is where the rules get specific. When a class implements an interface, the interface takes precedence over the base class, and when several interfaces are involved the precedence depends on the order the JVM returns them in. That last point is a real constraint for anyone relying on a stable result across environments. The order is not something the project controls, so two interfaces that both define the same annotation on the same member resolve by JVM ordering rather than by an explicit rule you can point at.

Adding the dependency to a Maven project

All annotations live in one package, and using them means adding one Maven dependency:

xml
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>${jackson-annotations-version}</version>
</dependency>

The version is left as a property in the example, so you control it in your own build. The alternative route stated by the project is to download the jars straight from the Maven repository, with quick links on the wiki. Once the dependency is on the classpath, a first real use is a renamed property. Declaring the JSON name explicitly changes the output:

java
public class Name {
  @JsonProperty("firstName")
  public String _first_name;
}

The JSON that results carries the declared name:

json
{ "firstName" : "Bob" }

instead of the field name. The same annotations work on method based getter and setter properties, not only on fields.

Renaming, ignoring and tolerating unknown properties

Three separate needs sit behind the ignore annotations. A property you never want written out is marked on the field:

java
public class Value {
  public int value;
  @JsonIgnore public int internalValue;
}

which yields:

json
{ "value" : 42 }

Properties that arrive in the JSON but have no place in your object are handled at class level by naming them:

java
@JsonIgnoreProperties({ "extra", "uselessValue" })
public class Value {
  public int value;
}

so input like the following is accepted without an unknown property failure:

json
{ "value" : 42, "extra" : "fluffy", "uselessValue" : -13 }

If you would rather ignore every property that has no counterpart in the class, the same annotation takes a flag:

java
@JsonIgnoreProperties(ignoreUnknown=true)
public class PojoWithAny {
  public int value;
}

The third form is the one most teams end up copying, and it silently discards input, which is a design decision rather than a default. Jackson does not fail on unknown properties by default, so the behaviour here is opt in.

Narrowing types on read and write

Jackson can pick a type you did not want in either direction. On deserialization your declared field type may be too general when you know the exact implementation to construct. On serialization Jackson defaults to the specific runtime type, and you may want only the supertype's content instead of everything the runtime class carries. Both are handled by a pair of annotations:

java
public class ValueContainer {
  // although nominal type is 'Value', we want to read JSON as 'ValueImpl'
  @JsonDeserialize(as=ValueImpl.class)
  public Value value;

  // although runtime type may be 'AdvancedType', we really want to serialize
  // as 'BasicType'; two ways to do this:
  @JsonSerialize(as=BasicType.class)
  // or could also use: @JsonSerialize(typing=Typing.STATIC)
  public BasicType another;
}

The reading and writing sides are deliberately separate annotations, which is the point. Widening a type on output and narrowing it on input are different decisions, and a single type hint would force one behaviour where the other is wanted. The static typing option is offered as an alternative to the class hint on the serialization side.

Constructors as the entry point for deserialization

By default Jackson instantiates values through the no argument constructor. When a class has no such constructor, or when you want a specific static factory method to do the creating, you point at it with @JsonCreator. Argument names are then bound with @JsonProperty on the parameters, and the README's example binds two of them:

java
public class CtorPOJO {
   private final int _x, _y;

   @JsonCreator
   public CtorPOJO(@JsonProperty("x") int x, @JsonProperty("y") int y) {
      _x = x;

Binding names to parameters is the part people forget. Without the @JsonProperty annotations on the arguments, the creator has no reliable way to map incoming JSON names onto parameters, and any implicit naming rule that your build happens to have will silently become part of your wire format. The trade-off of using a creator is that your object becomes constructible in exactly one way, which is usually what you want for immutable value types and occasionally annoying for classes that need other construction paths.

Where annotations stop and other approaches take over

Two boundaries define where this module stops being the answer. The first is the databind boundary: any annotation that needs the Databind package is not shipped here, so a feature you expect to find by name may live in a different artifact. The second is the code you do not own. Annotations on your own classes are the simple case, but for third-party types the mix-in mechanism exists precisely so you can attach the same annotation semantics without editing code you do not control. The in-project alternative to sprinkling annotations across a shared domain model is a set of mix-ins kept in one place. The other alternative is to let the databind layer carry the configuration, since that is where handling lives anyway, though the details of that configuration are outside this module. What this repository cannot do is make Jackson work on its own, and any evaluation that treats it as a standalone mapping library will misjudge it.

Editorial conclusion

Adopt jackson-annotations when your Java project already runs Jackson and you want JSON property names, ignore rules, type narrowing or creator binding declared on the type rather than scattered through configuration. Do not reach for it expecting serialization to work on its own, because every behaviour it names is implemented by jackson-databind, and skip the module entirely if you need annotations that require databind since those are not shipped here. Before you start, confirm the jackson-annotations version your databind release expects, read the Jackson-Annotations wiki listing for the full set, and check whether mix-ins would let you keep third-party classes free of annotations.

Frequently asked questions

What does jackson-annotations actually do?

It provides the annotation types and their related value classes, in the package com.fasterxml.jackson.annotation, for use on value and handler types. It contains no functionality that uses annotations, so nothing is serialized or deserialized by this module alone.

Which version of jackson-annotations should I depend on?

Since Jackson 2.20 the module is released with a simple version such as 2.20, with a patch number only for rare critical fixes, because earlier patch numbers were meaningless. Jackson 3.x components rely on the 2.x annotations, and no separate 3.x versions of this module were released.

How do I make Jackson ignore JSON properties that are not in my class?

Annotate the class with @JsonIgnoreProperties(ignoreUnknown=true). Alternatively, name the properties to ignore explicitly, as in @JsonIgnoreProperties({ "extra", "uselessValue" }).

Can I use Jackson annotations on a third-party class I do not control?

Yes, through mix-in annotations, which associate annotations with third-party classes without modifying the classes themselves. Annotation definitions are also inherited, and interfaces take precedence over base classes.

Official sources

  1. FasterXML/jackson-annotations on GitHub
  2. Issues
  3. License: Apache-2.0
  4. Project website
  5. README
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/fasterxml-jackson-annotations.svg)](https://hysenlabs.com/projects/fasterxml-jackson-annotations)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/fasterxml-jackson-annotations.svg)](https://hysenlabs.com/projects/fasterxml-jackson-annotations)

Was this useful?