Why Choose Juneau?
Apache Juneau™ combines a marshalling core with no required external dependencies, REST servers and clients that share one set of annotations, and in-process testing. Here's why developers choose Juneau over alternatives.
The Juneau Advantage
One Dependency Story
The juneau-marshall core needs only juneau-commons. A REST service adds the Jetty microservice bundle. Import the BOM once and leave versions off; see Install Juneau, and Framework Comparisons for how this compares.
Juneau:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-bom</artifactId>
<version>${juneau.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-microservice-jetty-bundle</artifactId>
<type>pom</type>
</dependency>
</dependencies>
Alternative (Spring Boot + Jackson + Swagger):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<!-- Plus many more dependencies -->
Unified API, Multiple Formats
Juneau provides a single, consistent API for serializing to multiple formats:
// One API, multiple formats
Person person = new Person("John", 30);
// JSON
String json = Json.of(person);
// XML
String xml = Xml.of(person);
// HTML
String html = Html.of(person);
// URL-Encoding
String urlEnc = UrlEncoding.of(person);
// ...and the rest of the 38 formats
With alternatives, you need different libraries and APIs for each format.
Self-Documenting REST APIs
Juneau automatically generates Swagger documentation from your POJOs and annotations:
@Rest(title="User API", description="User management service")
public class UserResource extends BasicRestServlet {
@RestGet("/users/{id}")
public User getUser(@Path("id") String id) {
return userService.findById(id);
}
@RestPost("/users")
public User createUser(@Content User user) {
return userService.create(user);
}
}
Result: Swagger UI at /swagger with full API documentation, request/response schemas, and interactive testing. The Swagger v2 document is at /api and OpenAPI 3.1 at /openapi.
Type-Safe REST Client Proxies
Create type-safe client interfaces that feel like local method calls:
// juneau-rest-client (org.apache.juneau.rest.client.RestClient)
@Remote("http://api.example.com")
public interface UserService {
@RemoteGet("/users/{id}")
User getUser(@Path("id") String id);
@RemotePost("/users")
User createUser(@Content User user);
}
// Use like a regular Java interface
UserService service = RestClient.builder().build().remote(UserService.class);
User user = service.getUser("123");
No more manual HTTP client code, JSON parsing, or error handling.
This uses juneau-rest-client, the recommended REST client. The Apache HttpClient-based juneau-rest-client-classic stays supported for existing users; see Choosing a REST Client.
Serverless Testing
Test REST APIs without starting servers or containers:
@Test
public void testUserAPI() throws Exception {
try (MockRestClient mock = MockRestClient.create(UserResource.class);
var resp = mock.get("/users/123").run()) {
resp.assertThat().isOk().body().contains("John");
}
}
Fast, reliable tests with no server or network.
Token and Record Streaming
Juneau 10 introduces a low-level streaming API for processing large datasets without buffering the entire document:
// Stream a large JSON5L (JSON5 Lines) file record-by-record — O(1) memory
try (RecordReader r = Json5l.DEFAULT.readRecords(inputStream)) {
while (r.canRead())
process(r.read(Person.class));
}
// Fine-grained structural token cursor (JSON, CBOR, MsgPack)
try (TokenReader r = Json.DEFAULT.readTokens(inputStream)) {
while (r.next() != TokenType.END_OF_STREAM) {
switch (r.getCurrentToken()) {
case FIELD_NAME -> System.out.print(r.getFieldName() + " = ");
case VALUE_STRING -> System.out.println(r.getString());
default -> { /* structural token, e.g. START_OBJECT/END_OBJECT */ }
}
}
}
RecordReader/RecordWriter work across every Juneau format; TokenReader/TokenWriter add fine-grained structural events for token-shaped formats (JSON family, CBOR, MsgPack). Both are first-class @RestOp parameter types, so REST endpoints can stream large responses directly to the client without intermediate buffering.
With alternatives, large-dataset streaming requires format-specific libraries and manual integration.
How Juneau Differs
Each point links to the matching section of Framework Comparisons, which states the evidence.
- Formats. 38 formats (26 in
juneau-marshall, 12 RDF injuneau-marshall-rdf) through one API: JSON, XML, HTML, YAML, CSV, MessagePack, MarkdownDoc and more.juneau-marshallcovers the core formats andjuneau-marshall-rdfthe RDF ones, where Jackson adds ajackson-dataformat-*module per format. See Juneau vs Jackson. - REST and API docs built in. Jackson is a data-binding library, not a REST framework. Spring Boot adds OpenAPI through an add-on such as SpringDoc, and JAX-RS through a separate library such as MicroProfile OpenAPI; Juneau generates it from
@Restand@RestOp. See Spring Boot and JAX-RS. - Content negotiation from one method. One Juneau method answers JSON, XML, HTML and the other registered formats based on
Accept. Spring needs separate methods orHttpMessageConverterconfiguration per format; JAX-RS supports it through@Produces/@Consumes, with format-specific handling done by hand. See Spring Boot and JAX-RS. - Testing without a server.
MockRestClientcalls a resource in-process. Spring uses@SpringBootTest/@WebMvcTestor embedded containers; for JAX-RS it depends on the implementation and its test tooling. See Spring Boot. - Annotations, not a container. Juneau and Spring are both annotation-based. JAX-RS is a specification that needs an implementation such as Jersey or RESTEasy. Juneau resources can also run inside Spring Boot. See JAX-RS.
Real-World Benefits
Enterprise Development
- Consistent APIs: Same patterns across serialization, REST services, and testing
- Built-in Documentation: Automatic Swagger generation reduces documentation maintenance
- Content Security Policy: First-class CSP header support with per-request nonce injection (10.0+), protecting the HTML UI and Swagger UI against XSS with a single opt-in setting
Microservices
- Flexible Deployment: Works with any Jakarta Servlet 6.1 container, embedded Jetty, or embedded Tomcat
- Easy Testing: MockRestClient enables comprehensive testing without external services
API Development
- Rapid Prototyping: A running REST API in about 10 minutes: see Getting Started
- Automatic Documentation: Swagger UI generated automatically from your code
- Content Negotiation: Support multiple formats with no per-format setup
- Type Safety: Compile-time checking for REST client interfaces
- MCP Support:
juneau-rest-server-mcp(revision-neutral core) plus thejuneau-rest-server-mcp-v20260728(current) andjuneau-rest-server-mcp-v20250618adapters expose any@Restresource as a Model Context Protocol (MCP) endpoint, enabling LLM tool-calling with no additional framework — client-side MCP support (juneau-rest-client-mcpand its revision adapters) is also available
When to Choose Juneau
This is guidance, not a measurement; for the feature-by-feature comparison see Framework Comparisons.
Perfect For:
- Multi-format APIs: When you need to support JSON, XML, HTML, and other formats
- Rapid Development: When you want to build APIs quickly without complex configuration
- Microservices: When you need lightweight services on embedded Jetty or Tomcat
- Testing: When you want comprehensive testing without external dependencies
- Documentation: When you need automatic API documentation generation
- Learning: When you want to understand REST APIs without framework complexity
Consider Alternatives If:
- Heavy Spring Ecosystem: You're already deeply invested in Spring Boot's ecosystem
- Complex Enterprise Features: You need advanced enterprise features like distributed transactions
- Large Team: Your team has extensive experience with other frameworks
- Legacy Integration: You need to integrate with existing Spring-based systems
Next
Getting Started builds and runs a REST app in about 10 minutes.
Community and Support
- Documentation: Comprehensive guides and examples at juneau.apache.org
- Examples: Working code examples in the juneau-examples repository
- Community: Join discussions on the Apache Juneau mailing list
- Issues: Report bugs and request features on GitHub Issues
Conclusion
Juneau offers an alternative to assembling several libraries. It provides a unified API for serialization, REST services, and testing, on a marshalling core with no required dependencies, so developers can focus on business logic rather than framework configuration.
Still not convinced? Check out our Framework Comparisons page for detailed technical comparisons, or explore our comprehensive examples to see Juneau in action.