
Java has never had a built-in JSON parser. In 2014, it almost did — JEP 198 proposed one for JDK 9, then got dropped when Oracle decided other features mattered more. Developers were told that “future language improvements might enable a better API.” That was twelve years ago. JEP 540, now in Incubator status and targeting JDK 28, is Oracle finally making good on that promise. It is small, limited by design, and long overdue.
What JEP 540 Actually Is
JEP 540 adds a Json class and a JsonValue type hierarchy to the JDK standard library. Parsing a JSON string becomes a single call: Json.parse(string) returns a tree of JsonValue objects. Generating JSON uses factory methods — JsonObject.of(...), JsonArray.of(...), JsonString.of(...). No Maven coordinates. No transitive Jackson dependencies pulling in three JARs. Just the JDK you already have.
The JsonValue hierarchy has six concrete types: JsonString, JsonNumber, JsonBoolean, JsonNull, JsonObject, and JsonArray. Values from objects and arrays are accessible directly on JsonValue without downcasting — a small but welcome ergonomic win over JSON-P, the enterprise JSON-Processing API that’s been on the books since Java EE.
The Code, Side by Side
Here is what reading a single field from a JSON response looks like today with Jackson, versus what it looks like on JDK 28 with JEP 540:
With Jackson (today)
// Requires: jackson-databind, jackson-core, jackson-annotations in pom.xml
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(jsonString);
String name = root.get("name").asText();
int age = root.get("age").asInt();
With JEP 540 (JDK 28+)
// Requires: --add-modules jdk.incubator.json
// Zero Maven dependencies
JsonValue doc = Json.parse(jsonString);
String name = doc.getValue("name").asString();
int age = doc.getValue("age").asInt();
For a script or a CLI tool that needs to read one field from an HTTP response, the JEP 540 version is plainly better. The Jackson version requires a dependency, which requires build tooling, which requires a project structure. The JEP 540 version works with a single Java file.
What It Does Not Do (And Why That Matters)
JEP 540 is not a Jackson replacement. The JEP makes this explicit: no data binding, no POJO serialization, no custom serializers, no streaming for large documents, no schema validation. If your application uses Spring Boot’s @RequestBody annotation to deserialize a request into a Java object, Jackson stays. That is not a bug — it is a deliberate scope decision.
The proposal targets a specific gap: simple tasks that currently require pulling in a library just to read a config file or parse one field from an API response. It fills that gap without attempting to replace what Jackson does for production APIs. Think of it as the tool you reach for before your project has a build file.
The Verbosity Problem Is Real
The Hacker News thread for JEP 540 surfaces a legitimate criticism. To generate {"name": "Alice", "age": 30}, you write this:
JsonObject result = JsonObject.of(Map.of(
"name", JsonString.of("Alice"),
"age", JsonNumber.of(30)
));
Every native Java value must be wrapped in a JsonString.of() or JsonNumber.of() call. You cannot pass a raw String or int. For an API whose stated goal is “low ceremony,” the current design is ironic. Developers on Hacker News put it bluntly: it feels like more work than it should be for something billed as simple.
This is worth flagging because JEP 540 is still an Incubator API — and community feedback is exactly how it changes before stabilizing. If you try it and find the verbosity painful, the JEP 540 specification page links to the mailing list where that feedback actually lands.
Incubator Means: Try It, Don’t Ship It
JEP 540 lives in the jdk.incubator.json module. To use it you need --add-modules jdk.incubator.json on the command line. Incubator APIs are explicitly unstable — they can be removed or redesigned between JDK releases without a deprecation cycle. The likely path forward:
- JDK 28 (March 2027): Incubator — experimental, API will change
- JDK 29 (September 2027): Likely Preview — more stable, still not production
- JDK 30+ or next LTS: Potential GA — production-ready
Use JEP 540 today for experimentation, prototypes, and internal tools where you control the JDK version. The Azul guide on Incubator vs Preview features is worth reading if you need to explain the distinction to your team. Do not take a production dependency on an Incubator API unless you enjoy painful upgrade cycles.
The Bigger Pattern
JEP 540 is not an isolated move. Java has spent the last decade systematically reducing the cases where you need an external library for basic tasks. Text Blocks removed multi-line string hacks (JDK 15). Records replaced Lombok data classes (JDK 16). Virtual Threads made reactive frameworks optional for concurrency (JDK 21). Pattern Matching reduced the casting boilerplate that drove developers to Kotlin and Scala.
JSON is the next item on that list. The InfoQ Java roundup for July 2026 frames JEP 540 alongside JEP 401 (Value Classes, Project Valhalla) and JEP 539 (Strict Field Initialization) as part of a broader push to modernize the standard library. The direction is clear even if the timeline is long.
Who Should Care Right Now
If you write Java CLI tools, build utility scripts, author test helpers, or work in environments with strict dependency audits, JEP 540 is worth tracking. Install JDK 28 early-access builds when they drop, add --add-modules jdk.incubator.json, and experiment with Json.parse(). Then give feedback — especially on the verbosity. That is how Incubator APIs become good Preview features.
If you run Spring Boot APIs in production, nothing changes today. JEP 540 is not for you yet. Keep Jackson, which remains the right tool for production data binding. Check back when JEP 540 graduates to GA — at that point the calculus for simple parsing tasks shifts meaningfully.
After 28 years of “just add Jackson to your pom.xml,” Java is finally building the on-ramp. It’s bumpy right now. That’s what Incubator means.












