Chappe is a high-performance HTTP server written in pure Java 25 with no runtime dependency outside the JDK. It implements HTTP/1.1 (RFC 9110/9112), HTTP/2 (RFC 9113) and — eventually — HTTP/3 (RFC 9114). It is the transport layer of the Vidocq ecosystem: Foy (Servlet) and Cassini (REST) mount on top.

Origin of the name

Claude Chappe (1763-1805), a French engineer, invented the optical telegraph that went into service in 1794. His network of 556 hilltop stations with articulated semaphores spanned France and could carry a message from Paris to Toulon in under fifteen minutes — the first real long-distance communication infrastructure, decades before Morse.

The metaphor holds in two ways:

  • Chappe (the server) is the transport layer — it moves bytes around with no application logic, exactly like an optical station relayed codes without interpreting them.

  • The French telegraph administration was later inherited by Alphonse Foy in the 19th century. In Vidocq, Foy (Servlet 6.1) inherits the Chappe transport in the same way.

At a glance

Implemented specs

HTTP/1.1 (RFC 9110, RFC 9112), HTTP/2 (RFC 9113), HTTP/3 (RFC 9114, planned)

Repo

https://codeberg.org/Vidocq/chappe

Java

25 (LTS)

JPMS modules

io.vidocq.chappe.api, io.vidocq.chappe.http, io.vidocq.chappe.core, io.vidocq.chappe.cli

Runtime dependencies

none (JDK only)

Conformance

45 RFC tests in chappe-conformance; 113 integration tests in chappe-tests

TCK

not applicable (no official HTTP TCK)

Position in the ecosystem

Chappe sits at the heart of transport: every Vidocq module that speaks HTTP goes through it.

Diagram

Chappe also runs without any extension: that is what its chappe serve CLI does to ship a static site to production.

Identity traits

  • Strict Java 25ScopedValue (JEP 506), exhaustive pattern matching, sealed interfaces, records.

  • Virtual threads — one virtual thread per connection, no platform pool, no application-side Selector.

  • Strict JPMS — every module ships a module-info.java, minimal exports, no classpath fallback.

  • Zero dependency — no transitive logger, no external utility library. JUnit only for tests.

  • Static codegenchappe-static-index-maven-plugin produces the O(1) index and .gz sidecars at build time.

  • Zero-copy I/OFileChannel.transferTo() for static files and pre-compressed sidecars.

Performance

Quick read (TL;DR, canonical table, JFR profile, native vs JVM): Performance page. The full log of all runs (closed-loop in-process and open-loop wrk2), detailed methodology and history of optimizations live in lien:https://codeberg.org/Vidocq/chappe/blob/main/BENCHMARKS.md[BENCHMARKS.md].

  • Getting started — first server in under 30 lines.

  • Usage — TLS, HTTP/2, virtual hosts, static files, compression, CLI.

  • Concepts — connection, frame, multiplexing, scoped values.

  • Internals — HTTP/1.1, HTTP/2, HTTP/3 pipelines; threading model.

  • Reference — Maven coordinates, JPMS packages, public API, Maven plugin.

  • Migration — from Netty, Undertow, Jetty, JDK HttpServer.