Liking cljdoc? Tell your friends :D

Zeph

A cross-platform HTTP server & client for Clojure using Java NIO.

Features

  • Cross-platform - Works on Linux, macOS, and Windows
  • Ring compatible - Drop-in replacement for http-kit/Jetty
  • HTTP/2 - h2 (ALPN) and h2c (cleartext upgrade)
  • SSL/TLS - HTTPS with PEM or PKCS12 certificates
  • HTTP Client - http-kit compatible Promise API with connection pooling
  • Streaming - Efficient large file serving with sendfile()
  • Static files - Built-in static file serving with MIME types
  • GraalVM - Native image support for instant startup

Requirements

  • Java 17+
  • Clojure 1.11+

Quick Start

Server

(require '[zeph.server :as server])

(def stop (server/run-server
            (fn [req] {:status 200 :body "Hello!"})
            {:port 8080}))

;; Stop
(stop)

Client

(require '[zeph.client :as http])

@(http/get "https://example.com")
;; => {:status 200 :headers {...} :body "..."}

Installation

;; deps.edn
{:deps {io.gitlab.myst3m/zeph {:mvn/version "0.2.1"}}}

;; Leiningen
[io.gitlab.myst3m/zeph "0.2.1"]

Server

Basic Usage

(require '[zeph.server :as server])

(defn handler [req]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, World!"})

(def stop (server/run-server handler {:port 8080}))

;; Stop server
(stop)

Options

OptionDefaultDescription
:port8080Port number
:ip"0.0.0.0"Bind address
:threadCPU coresWorker threads
:ssl?falseEnable HTTPS
:certnilCertificate PEM path
:keynilPrivate key PEM path
:keystorenilPKCS12/JKS keystore path
:keystore-passwordnilKeystore password
:static-rootnilStatic files directory

SSL/TLS

;; Built-in localhost certificate
(server/run-server handler {:port 8443 :ssl? true})

;; PEM files
(server/run-server handler {:port 8443
                            :ssl? true
                            :cert "cert.pem"
                            :key "key.pem"})

;; PKCS12 keystore
(server/run-server handler {:port 8443
                            :ssl? true
                            :keystore "keystore.p12"
                            :keystore-password "secret"})

HTTP/2

HTTP/2 is automatically enabled:

  • h2 - Over TLS via ALPN negotiation
  • h2c - Cleartext via HTTP/1.1 Upgrade header

Test with curl:

# HTTP/2 over TLS (h2)
curl -v --http2 https://localhost:8443/

# HTTP/2 cleartext (h2c)
curl -v --http2 http://localhost:8080/

Look for HTTP/2 200 in the output to confirm HTTP/2 is working.

Streaming Responses

Large files are streamed efficiently without loading into memory:

(require '[clojure.java.io :as io])

;; File - sets Content-Length automatically
{:status 200 :body (io/file "/path/to/large.bin")}

;; InputStream - uses chunked encoding
{:status 200 :body (io/input-stream "/path/to/large.bin")}

Static Files

(server/run-server handler {:port 8080
                            :static-root "public"})
;; Serves files from ./public directory
;; Example: GET /css/style.css -> ./public/css/style.css

Ring Request

{:server-port    8080
 :server-name    "localhost"
 :remote-addr    "127.0.0.1"
 :uri            "/path"
 :query-string   "foo=bar"
 :scheme         :http
 :request-method :get
 :protocol       "HTTP/1.1"
 :headers        {"host" "localhost"}
 :body           nil}

Client

Basic Usage

(require '[zeph.client :as http])

;; GET
@(http/get "https://example.com")

;; POST with JSON
@(http/post "https://api.example.com/data"
            {:body "{\"key\":\"value\"}"
             :headers {"Content-Type" "application/json"}})

;; Async with callback
(http/get "https://example.com"
          (fn [{:keys [status body error]}]
            (println status)))

Options

OptionDefaultDescription
:method:getHTTP method
:headersnilRequest headers
:bodynilRequest body
:query-paramsnilQuery parameters
:form-paramsnilForm parameters
:timeout30000Timeout (ms)
:follow-redirectstrueFollow redirects
:max-redirects5Max redirects
:insecure?falseSkip SSL verification
:basic-authnil["user" "pass"]

Promise API

;; Blocking
@(http/get url)

;; With timeout
(deref (http/get url) 5000 :timeout)

;; Check completion
(realized? (http/get url))

Response

;; Success
{:status 200 :headers {...} :body "..."}

;; Error
{:error #<Exception ...>}

CLI

Zeph includes an HTTPie-style CLI. Client is the default command.

# Basic requests (client is default - no subcommand needed)
zeph httpbin.org/get
zeph POST httpbin.org/post name=John age:=30

# Nested JSON syntax
zeph httpbin.org/post user.name=John user.email=john@example.com
# => {"user": {"name": "John", "email": "john@example.com"}}

zeph httpbin.org/post items.0=apple items.1=banana
# => {"items": ["apple", "banana"]}

# Options
zeph -X httpbin.org/get              # trace with headers/body
zeph -V httpbin.org/get              # trace summary
zeph -1 httpbin.org/get              # force HTTP/1.1
zeph -k https://self-signed/api      # skip SSL verify

# Server
zeph s -p 8080
zeph s -p 8443 --ssl

Request Items

SyntaxDescriptionExample
key=valueJSON stringname=John -> {"name": "John"}
key:=valueRaw JSONage:=30 -> {"age": 30}
a.b=valueNested objectuser.name=John -> {"user": {"name": "John"}}
a.0=valueArray elementitems.0=x -> {"items": ["x"]}
Header:ValueHTTP headerAuthorization:Bearer token

Building

Development

clojure -T:build compile-java
clojure -X:test
clojure -M:dev

JAR

clojure -T:build uberjar
java -jar target/zeph-*-standalone.jar server -p 8080

Native Image

GRAALVM_HOME=/path/to/graalvm clojure -T:build native-image
./target/zeph server -p 8080

Architecture

+---------------------------------------------------------------+
|                         Zeph Server                           |
+---------------------------------------------------------------+
|                    HttpServer Interface                       |
|                           |                                   |
|                           v                                   |
|                     HttpServerNio                             |
|                    (Cross-platform)                           |
|                           |                                   |
|                           v                                   |
|                   +---------------+                           |
|                   |   Selector    |                           |
|                   |   Workers     |                           |
|                   | (NIO +        |                           |
|                   |  sendfile)    |                           |
|                   +---------------+                           |
+---------------------------------------------------------------+
|                      Java NIO Selector                        |
+---------------------------------------------------------------+

Branches

  • main - NIO-only, cross-platform (Linux/macOS/Windows)
  • io_uring - io_uring + NIO, Linux high-performance version

Limitations

  • No WebSocket support (planned)
  • No async handlers (planned)

License

EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0

Can you improve this documentation?Edit on GitLab

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close