What’s Jetty?
Jetty is an open-source Java-based HTTP server and servlet container. It’s what actually listens on a port, accepts incoming HTTP requests, and hands them off to your application.
In the context of Clojure/Ring:
Since Clojure runs on the JVM, it can use Java libraries directly. Ring provides an adapter called ring-jetty-adapter that bridges your Clojure handler functions with Jetty’s Java internals. So the flow looks like:
Browser request
↓
Jetty (Java HTTP server — listens on port 3000)
↓
ring-jetty-adapter (translates Java HTTP → Clojure map)
↓
Your Ring handler (just a Clojure function)
↓
ring-jetty-adapter (translates Clojure map → Java HTTP response)
↓
Jetty (sends response back to browser)
Why Jetty specifically?
It’s the default in the Ring/Compojure ecosystem because it’s:
- Embeddable — runs inside your app’s process, no separate server install needed
- Lightweight — starts fast, low overhead for development
- Battle-tested — used in production by many large projects (Eclipse IDE, Hadoop, etc.)
Starting it in your Compojure project:
;; In your handler.clj or core.clj
(use 'ring.adapter.jetty)
(run-jetty app {:port 3000})
Or just via Leiningen:
lein ring server
This spins up Jetty on port 3000 and serves your Compojure routes.
Alternatives to Jetty in the Clojure world:
| Server | Library |
|---|---|
| Jetty | ring-jetty-adapter |
| HTTP Kit | http-kit |
| Undertow | ring-undertow-adapter |
| Netty | aleph |
They’re all interchangeable from Ring’s perspective — your handler code stays the same regardless of which server sits underneath.