Serve web requests using Ring handlers, Servlets, or Undertow HttpHandlers


(run handler & options)

Runs handler with the given options.

handler can be a Ring handler function, a Servlet, or an Undertow HttpHandler. Can be called multiple times - if given the same options, any prior handler with those options will be replaced. Returns the given options with any missing defaults filled in.

options can be a map or kwargs, with these valid keys [default]:

  • :host The interface bind address [“localhost”]
  • :port The port listening for requests [8080]
  • :path Maps the handler to a prefix of the url path [“/”]
  • :virtual-host Virtual host name[s] (a String or a List of Strings) [nil]
  • :dispatch? Invoke handlers in worker thread pool [true]

Note the web server only binds to the loopback interface, by default. To expose your handler to the network, set :host to an external IP address, or use “” to bind it to all interfaces.

The :virtual-host option enables name-based virtual hosting which, along with the :path option, distinguishes the handlers on a single server. That is, multiple handlers can run on the same :host and :port as long as each has a unique combination of :virtual-host and :path.

Run calls may be threaded together:

  (-> (run ello)
    (assoc :path "/owdy")
    (->> (run owdy))
    (merge {:path "/" :port 8081})
    (->> (run ola)))

The above actually creates two web server instances, one listening for ello and owdy requests on port 8080, and another listening for ola requests on 8081.

The underlying web server for Immutant is Undertow, which supports more advanced options than the above. These can be configured by passing an Undertow$Builder instance via the :configuration option, and that instance is easily constructed from a Clojure map using the immutant.web.undertow/options function.

If your handlers are compute-bound, you may be able to gain some performance by setting :dispatch? to false. This causes the handlers to run on Undertow’s I/O threads, avoiding the context switch of dispatching them to the worker thread pool, at the risk of refusing client requests under load.

When used inside WildFly, any calls to run must be within the initialization function for your application (your -main).



(run-dmc handler & options)

Run in Development Mode (the ‘C’ is silent).

This macro invokes run after ensuring the passed handler is var-quoted, with reload and stacktrace middleware applied, and then opens the app in a browser. Supports the same options as run.


(server & options)

Returns the web server instance associated with a particular set of options, typically the map returned from a run call. The web server provides start, stop and isRunning methods, allowing you to, for example, temporarily stop serving requests for all the handlers running on a particular server.

  (let [srv (server (run hello :auto-start false))]
    (.isRunning srv)   ;=> false
    (.start srv)
    (.isRunning srv)   ;=> true
    (.stop srv))

The return value is either a single server instance or a list of servers if passed the result from threaded run calls that would cause multiple servers to be created.


(stop & options)

Stops a running handler.

options can be passed as a map or kwargs, but is typically the map returned from a run call. If that return value is not available, you can pass the same options map passed to run for the handler you want to stop. If options isn’t provided, the handler at the root context path (“/”) of the default server will be stopped. If there are no handlers remaining on the server, the server itself is stopped. Returns true if a handler was actually removed.