What Web Framework Should I Use in Clojure?
Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.
In this guide, I describe the available web framework options for Clojure and give my recommendations.
Roll your own stack from recommended libraries (coming soon) if you are just learning. It will be the best way to understand how everything works.
Use Pedestal if you want a production-tested foundation on which to build your application.
Use Luminus if you want the flexibility of rolling your own stack without the work involved.
One question that I am asked a lot by beginners in Clojure is "What web framework should I use?" This is a good question. In Python, there's Django. In PHP, Drupal. And of course in Ruby, there's the king of all web frameworks, Ruby on Rails. But in Clojure, this is a difficult question to answer. Even deciding what is a framework and what is a library can be difficult. We will have to address that first.
What is (and isn't) a web framework
For the purposes of this guide, we will define a web framework as a collection of code and dependencies that provide a holistic approach to building a web application. This definition rules out several libraries that are commonly called frameworks, such as Compojure and Ring, since those don't, by themselves, give you an approach. However, there are still several great contenders which I consider here.
Because rolling your own stack is a common alternative in Clojure to using a pre-built framework, and it can be considered a holistic approach (namely, build your application from existing libraries), I consider that in the recommendations as well.
The purpose of this guide is to give strong recommendations for web frameworks for different needs. Here are the criteria I examine about each framework:
Does the framework have easy-to-follow documentation? I look for beginner tutorials through advanced topics.
A large, active community is an important part of a framework's viability. A large community can more easily provide, keep dependencies up to date, and build a more complete solution.
The age of a project, and how long it has been used in production in large-scale sites, is another important factor. I prefer older frameworks that have been deployed for significant sites.
Since a framework must provide a holistic approach, the approach itself must be taken into account. How does the framework approach building an application?
When your application is ready, it needs to be deployed. What deployment options are available? A wider variety is better.
Roll your own
It feels weird to me to say this, but the best option for beginners is still to roll your own. Rolling your own stack is not as difficult as it may seem. You can do build a functional stack from a handful of libraries. Quite often, the more robust, built for you frameworks have made hundreds of decisions for you about how to build the stack, but they still require you to understand the legion of libraries they chose.
Besides being good for learning, rolling your own gives you complete control to support or not support a given feature.
The biggest drawback is that you must make a lot of decisions for yourself. There are many libraries out there and choosing among them can be a difficult proposition. One consolation is that, when putting your own libraries together, at least in Clojure, it is relatively easy to switch libraries if you find that one doesn't work for you.
When you do want a more complete solution (and you will), if you continue to build it yourself, you will arrive at something that is very much like the more robust frameworks. I would recommend switching to one of the other recommended solutions rather than building your own complete framework. Luckily, switching between them is easy since they all work on the Ring standard.
Pedestal is a mature set of libraries, originally created by Cognitect, for developing modern, streaming web applications. It is built around long-lived connections that allow you to stream data from the server to the client over time. To support that feature, Pedestal invented the idea of interceptors, which give you a way to define pipelines of asynchronous steps that your request goes through.
I recommend Pedestal because it is mature, has an active community, it supports a large variety of deployment options, and it has good support for web applications. The two knocks against it are its documentation and its lack of a unifying approach. It has some guides that will get you through basic Hello, World! applications. But I have not found anything that will explain how a complete application should be put together. The approach Pedestal facilitates is to provide the low-level groundwork you will need, like a pedestal on which to stand a bit taller than starting from scratch. To be sure, that groundwork is important, but a lot is left to the developer to choose and build themselves. For example, it purposefully does not have an HTML templating solution. It calls that "API-first". I would expect a complete web framework to have a solution for creating HTML.
Despite these issues, I recommend Pedestal as a solid and flexible foundation on which to build applications.
Luminus is essentially a template project. You create a new web application from that template, and everything is set up for you. Luminus gives you some options for the template, but in general, its approach is to make the choices for you---sometimes providing its own libraries and sometimes using existing libraries. When your project is created, you will have a complete web stack that is yours to build on or modify as you see fit. The main advantage is the unified vision that guided the choices of libraries.
Luminus aims to provide everything you need to write web applications. You get everything from routes, to session management, to ClojureScript compilation, to database migrations. It all comes pre-configured, so you can get started with your application logic right away. Think of Luminous like the set of libraries and configurations you would build yourself over 10 years of work on an application. You might not need it at first, but eventually you will want security, logging, internationalization, among other concerns. Luminus gives that to you with one command.
The main drawback with Luminus is that many of the libraries are exposed directly. Yes, that gives you the power to configure them as you will. But it also means you have a lot to understand if you want to build on the default behavior. Luckily, the documentation story is excellent. There is even a book which documents the recommended approach to building a web application using Luminus.
In addition, it has been around for years, been deployed for large applications, and has a variety of deployment options.
Other frameworks of note
These frameworks are interesting for their innovative approaches.
Fulcro is a fullstack solution. It uses React on the frontend, but it has a complete data model from client to database. If that kind of unifying vision is appealing, give it a try. There is excellent documentation and it is still actively developed.
Duct is a leiningen template that approach building a web application as a set of configurations. For instance, in Duct, routing is a configuration. Migration is a configuration. Using this unifying, data-oriented approach, you build a web application that can be reloaded deterministically. The framework seems to be getting traction.
Tadam has configured a number of existing libraries and created a standard directory structure to make writing simple sites very easy. It is still new but active.
Coast on Clojure gives you a full solution (database to serving HTML) while focusing on keeping things simple.
Hoplon is a fullstack solution with an interesting approach. The frontend part compiles ClojureScript and lets you build interactive components that use a spreadsheet-like dataflow model. It can connect to the backend by calling functions that are proxies of functions on the server. This lets you bypass the whole routing situation. Development on it is slow.
These frameworks are not recommended because they have not been actively developed for too long and never got enough traction. I have not evaluated them on technical merits because I wouldn't recommend them based on their inactive development alone.
These projects are often called frameworks but they do not meet the definition of "providing a holistic approach to building a web application". I have not evaluated them here.
- Compojure - mostly a routing library with some conveniences
- yada - a powerful HTTP resource library for building standards compliant handlers
- Reitit - a routing library