JEP 540: Simple JSON API (Now in Incubator) – A New Era for Java JSON Parsing

Introduction

JSON (JavaScript Object Notation) has become the de facto standard for data interchange in modern software development. From REST APIs to configuration files, JSON is everywhere. Yet, for years, Java developers have had to rely on third-party libraries like Jackson, Gson, or JSON-B to parse and generate JSON. While these libraries are powerful, they introduce external dependencies, version conflicts, and learning curves. The Java community has long awaited a native, lightweight solution.

In July 2026, the OpenJDK project took a significant step forward by releasing JEP 540: Simple JSON API as an incubator module. This proposal, now available for preview in JDK 24, aims to provide a standard, minimal JSON parsing and generation API directly in the JDK. The goal is not to replace full-featured libraries but to offer a simple, zero-dependency alternative for common use cases.

This article delves into the details of JEP 540, explores its design principles, and provides practical examples. We will analyze how this new API can simplify your codebase, reduce build complexity, and improve maintainability. Whether you are a seasoned Java architect or a junior developer, understanding this JEP is crucial for staying ahead in the evolving Java ecosystem.

What is JEP 540?

JEP 540, officially titled "Simple JSON API," is a proposal to introduce a minimal JSON API into the Java Development Kit (JDK). It is currently in the incubator stage, meaning it is not yet a permanent part of the platform. Incubator modules allow developers to test and provide feedback on experimental features before they are finalized.

The API is designed around three core principles:
1. Simplicity: It provides only the essential operations for parsing and generating JSON.
2. Immutability: Parsed JSON objects are immutable by default, promoting thread safety.
3. No dependencies: The API relies solely on the JDK, eliminating the need for external libraries for basic JSON tasks.

According to the official JEP description, the API targets use cases such as processing simple JSON data from web services, reading configuration files, or generating JSON for logging. It intentionally avoids advanced features like data binding, streaming, or schema validation, leaving those to dedicated libraries.

The incubator module is available in JDK 24 and later builds. Developers can enable it using the --add-modules jdk.json flag.

Key Features and Examples

Let's explore the main components of the API with practical code snippets.

1. Parsing JSON

The entry point for parsing is the Json class. It provides static methods to parse a JSON string or an InputStream into a JsonValue. The JsonValue class is sealed, with three subtypes: JsonObject, JsonArray, and JsonPrimitive.

import jdk.json.*;

String jsonString = "{\"name\": \"Alice\", \"age\": 30, \"active\": true}";
JsonObject user = Json.parse(jsonString).asObject();

String name = user.get("name").asString(); // "Alice"
int age = user.get("age").asInt();        // 30
boolean active = user.get("active").asBoolean(); // true

Notice the use of asObject(), asString(), etc. These methods perform safe type conversions and throw exceptions if the types mismatch. This design ensures type safety without requiring generics.

2. Generating JSON

Generating JSON is equally straightforward. You can build a JsonObject using its builder pattern:

JsonObject person = Json.object()
    .add("name", "Bob")
    .add("age", 25)
    .add("address", Json.object()
        .add("city", "New York")
        .add("zip", "10001"))
    .build();

String output = person.toString();
// {"name":"Bob","age":25,"address":{"city":"New York","zip":"10001"}}

Arrays are built similarly:

JsonArray scores = Json.array()
    .add(95)
    .add(87)
    .add(92)
    .build();

3. Working with Primitive Values

The API supports the standard JSON primitives: strings, numbers (integer and floating-point), booleans, and null. JsonPrimitive provides methods like asString(), asInt(), asDouble(), asBoolean(), and isNull(). For example:

JsonPrimitive value = Json.value(42);
int number = value.asInt(); // 42

JsonPrimitive nullValue = Json.nullValue();
boolean isNull = nullValue.isNull(); // true

4. Error Handling

Parsing invalid JSON throws a JsonException, which is a subclass of RuntimeException. This design choice simplifies error handling in simple scripts but may require explicit try-catch blocks in production code.

try {
    Json.parse("{invalid}");
} catch (JsonException e) {
    System.err.println("Invalid JSON: " + e.getMessage());
}

Comparison with Third-Party Libraries

To understand the value of JEP 540, it is helpful to compare it with popular alternatives. The table below highlights key differences:

Feature JEP 540 (Incubator) Jackson Gson
Dependencies None (JDK only) External library External library
API Size Minimal (~10 classes) Extensive (~1000 classes) Moderate (~100 classes)
Data Binding No (manual mapping) Yes (automatic) Yes (automatic)
Streaming No Yes (JsonParser, JsonGenerator) No (but can be simulated)
Performance Good for small payloads Excellent for large payloads Good for most cases
License GPL v2 + CE Apache 2.0 Apache 2.0
Maturity Experimental Mature (20+ years) Mature (15+ years)

As the table shows, JEP 540 is not a competitor to Jackson or Gson for complex scenarios. Instead, it is a lightweight alternative for projects that want to avoid external dependencies, such as microservices, CLI tools, or educational projects.

Real-World Use Cases

1. Configuration Files

Many applications read JSON configuration files. With JEP 540, you can do this without adding a library:

import java.nio.file.*;
import jdk.json.*;

Path configPath = Path.of("config.json");
String content = Files.readString(configPath);
JsonObject config = Json.parse(content).asObject();

String dbUrl = config.get("database").asObject().get("url").asString();
int port = config.get("server").asObject().get("port").asInt();

2. Simple REST API Client

When making HTTP requests to REST APIs that return small JSON payloads, JEP 540 can be used directly:

import java.net.http.*;
import jdk.json.*;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/user/123"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject user = Json.parse(response.body()).asObject();

3. Logging and Metrics

Generating JSON for logs or metrics is simplified:

JsonObject logEntry = Json.object()
    .add("level", "INFO")
    .add("message", "User logged in")
    .add("timestamp", System.currentTimeMillis())
    .build();

logger.info(logEntry.toString());

Potential Limitations and Considerations

While JEP 540 is promising, developers should be aware of its limitations:
- No data binding: You must manually extract values, which can be verbose for deep nested objects.
- No streaming: For large JSON files (e.g., gigabytes), the API loads the entire data into memory. Use Jackson or a streaming parser for such cases.
- Incubator status: The API is subject to change. Future JDK versions may modify or remove it.
- Limited numeric precision: The API uses double for floating-point numbers, which may lose precision for very large values. Workarounds involve using string parsing.

How to Get Started

To try JEP 540 today:
1. Download JDK 24 or later from jdk.java.net.
2. Compile your code with --add-modules jdk.json:
bash javac --add-modules jdk.json MyClass.java
3. Run with the same flag:
bash java --add-modules jdk.json MyClass
4. Experiment with the examples above.

Conclusion

JEP 540 marks a significant milestone for the Java platform. By providing a native, minimal JSON API, the OpenJDK project addresses a long-standing gap in the standard library. While it is not a replacement for full-featured libraries, it offers a clean, dependency-free solution for simple JSON tasks.

As the incubator evolves, the community's feedback will shape its future. Developers are encouraged to test the API, report bugs, and suggest improvements. If you are working on a project that currently uses Jackson or Gson just for basic parsing, consider switching to JEP 540. It might simplify your build and reduce technical debt.

For more details, refer to the official JEP document: Source

Stay tuned for future updates as this API matures and potentially becomes a permanent part of the JDK.

Excerpt: JEP 540 introduces a simple, dependency-free JSON API as an incubator module in JDK 24. This article explores its features, provides code examples, and compares it with Jackson and Gson. Learn how to parse and generate JSON without external libraries.

← All posts

Comments