Learn how Ring, Reitit, Compojure, Luminus, and Pedestal fit together so you can choose a Clojure web stack by role and constraints instead of by brand names alone.
Clojure web stack: The layered ecosystem built around Ring handlers, routing libraries, middleware, starter stacks, and alternative request pipelines such as Pedestal interceptors.
Choosing a Clojure web framework gets easier once you stop treating every name as a full replacement for every other name. Most of the ecosystem is compositional. Ring is the foundation. Routers such as Reitit and Compojure sit on top. Starter stacks such as Luminus package a set of choices together. Pedestal is the main alternative execution model when interceptors and its service pipeline are a better fit than plain Ring middleware.
The strongest first question is not “Which framework wins?” It is “Which layer am I actually choosing?”
Once you separate those roles, the landscape feels much less confusing.
It also becomes easier to review existing systems honestly. Many teams are not really choosing “a framework.” They are choosing:
Ring remains the most important mental model in Clojure web work because it keeps HTTP close to ordinary data transformation. A handler consumes a request map and returns a response map. Middleware wraps handlers. That model is small, stable, and easy to compose.
Even teams that later adopt richer routing or alternative service layers still benefit from understanding Ring well, because so many libraries either implement Ring directly or feel similar to it.
1(defn health-handler [_]
2 {:status 200
3 :headers {"content-type" "text/plain; charset=utf-8"}
4 :body "ok"})
If your service is relatively conventional and your team values transparency over framework ceremony, Ring is the right starting point.
Compojure is the classic concise routing DSL. It still works well when you want small, readable route declarations and do not need heavy data-driven routing features.
Reitit is usually the stronger choice when you want richer routing metadata, parameter coercion, swagger or OpenAPI integration, or a routing layer that behaves more like structured data than macro-driven declarations.
That difference matters in larger APIs.
For many greenfield APIs, Ring plus Reitit is a practical default.
That does not make Compojure obsolete. It makes the trade-off clearer: concise routing syntax versus richer route metadata and tooling.
Luminus is best understood as a productivity stack rather than as a fundamentally different execution model. It brings together common choices such as routing, templating, persistence, and authentication so a team can move faster without assembling everything by hand.
That is useful when:
It is less useful when you want a very small service, highly customized architecture, or a carefully trimmed dependency surface.
Pedestal is the main ecosystem choice that genuinely changes the request-processing model. Instead of Ring middleware, it emphasizes interceptors, which can participate in both the inbound and outbound parts of the request lifecycle with more explicit control over flow.
That makes Pedestal attractive when:
It also means the mental model is different enough that teams should choose it intentionally rather than casually.
Pedestal is strongest when the team wants request processing to be expressed as a pipeline of explicit steps with richer context flow than plain Ring middleware usually provides. It is weaker if the team mostly wants a simple handler-and-router stack and has no need for interceptor-style composition.
A useful reminder for new teams is that no stack choice decides:
Framework selection matters, but it does not rescue unclear architecture. A clean Ring application with modest libraries often beats a theoretically richer stack wrapped around fuzzy boundaries.
Most real Clojure web systems do not pick every layer at once forever. They evolve.
A common path looks like:
That is one reason minimal clear foundations age well. They let the application grow by adding explicit layers instead of rewriting from framework fashion to framework fashion.
If you are building:
There is no prize for choosing the most flexible stack if your team mostly needs clear routes and simple handlers.
Picking Reitit or Compojure does not decide your domain design, persistence boundaries, or deployment strategy. It only decides part of the HTTP layer.
A full application stack can be helpful, but it can also add more moving parts than a small service actually needs.
Pedestal is not automatically overkill. It is simply a different model. If interceptors match how the team wants to express request processing, it may be the right choice.
The wrong familiar stack is usually better than the theoretically best stack nobody on the team can operate confidently.
Before choosing, ask:
Those questions are usually more useful than reading feature checklists in isolation.