This guide covers:

  • popular tools and libraries for web development

This work is licensed under a Creative Commons Attribution 3.0 Unported License (including images & stylesheets). The source is available on Github.

What Version of Clojure Does This Guide Cover?

This guide covers Clojure 1.11.

Overview

The web development space for Clojure is large and still evolving. Your options start with basic server-side web applications, generating HTML from either Clojure data structures or from more traditional template files, and can go all the way to full-stack web "frameworks" where you build a "single page application" (SPA) in ClojureScript for the frontend and a Clojure-powered API for the backend.

This guide doesn't clam to be comprehensive, but it does try to cover the most popular and well-maintained options, across that spectrum.

Static Sites

Before we get into web applications, it's worth mentioning that there are several Clojure-based solutions for generating static sites.

  • cryogen - simple static site generator written in Clojure
  • stasis - some Clojure functions for creating static websites

The README for the latter lists several other options.

You can also add ClojureScript interactivity to a static site using scittle which exposes the Small Clojure Interpreter to the browser.

Note: this can even support Reagent and re-frame, which are ClojureScript wrappers around React, but without the complexity of a full-blown SPA. See UI-Focused options in the Frontend Development section below.

Fundamentals

If you're building any backend component for a web application, you're going to need a web server and some sort of routing mechanism (mapping HTTP requests and URLs to Clojure functions that handle them).

Ring and Compojure

Perhaps the simplest and most minimal setup is to use only Ring and Compojure. To get started, see the basic web development tutorial.

In addition to the long-established Ring server library, which has an adapter for Jetty 9.4.x as the underlying web server, here are some alternatives:

  • http-kit - simple, high-performance, Ring-compatible web server
  • aleph - asynchronous communication server, including a Ring-compatible web server
  • sunng87 ring adapter - Ring adapter for Jetty 12 and 11

All three of those alternatives also support WebSockets (Ring 1.10 does not). As of this writing, Ring 1.11 is in development and will have an adapter for Jetty 11, as well as WebSocket support.

For routing, while Compojure is the most well-established and maybe most popular option, it is based on macros and some people prefer something more data-oriented, such as reitit.

HTML Templating

If you are generating HTML pages on the server, you will want a library to simplify that task.

The two most popular options are probably:

  • hiccup - generate HTML from Clojure data structures
  • selmer - Django-inspired templating library

If you are going to collaborate with frontend developers who are not familiar with Clojure, Selmer can be an excellent choice since the templates are written as HTML with a range of embedded variables, loops, and conditionals that will be familiar to anyone who has used a templating library in another language.

If you are working entirely with Clojure and ClojureScript developers, you may prefer to work mainly with Clojure data structures, and use Hiccup to generate HTML from those.

Hiccup-style data structures are also used in several ClojureScript libraries.

Frameworks and Integrated Libraries

Although Clojure eschews the idea of a "framework" in favor of composable libraries, there are a few "framework"-like options that are popular as "batteries-included" choices for web development.

Luminus

Probably the most well-established choice in this category is Luminus, which is driven by a Leiningen template for creating batteries-included web applications. In its most basic form, it uses Ring, reitit, Mount, and the JBoss Undertow web server.

However, it offers options to create web application projects that use a wide variety of different libraries:

  • aleph, http-kit, or jetty for web servers
  • h2, mysql, postgres, or sqlite for traditional databases
  • datomic or xtdb for temporal databases with a datalog query language
  • mongodb for a document database
  • REST or GraphQL for APIs, with optional Swagger-UI support
  • reagent, re-frame, shadow-cljs, etc for frontend development

and many other options.

Kit

From the same author as Luminus, Kit is a lightweight, modular framework for scalable web development in Clojure. It builds on the lessons learned from Luminus and should be considered a modern alternative to it.

Unlike Luminus, it uses the Clojure CLI and clj-new to create and run new projects. In its most basic form, it uses Ring, reitit, integrant, aero (for handling configuration), and the JBoss Undertow web server.

Like Luminus, you can add a wide variety of different libraries to your web application projects -- however, Kit is more modular than Luminus and lets you add new libraries to your project more easily, after you have created it, instead of having to choose all the libraries up front.

You can use HTMX with Kit via the ctmx module.

Biff

Biff is a batteries-included web framework for Clojure that is fairly opinionated about the libraries it uses. It is based on Ring (but using the sunng87 adapter for the Jetty 11 web server), reitit, XTDB for the database, with malli to provide schema definition and validation, and produces HTML that uses HTMX to provide an interactive experience without the complexity of a full-blown SPA.

JUXT Site

Site is a platform for building stateful API services. It is based on XTDB for the database, supports OpenAPI and OpenID, and provides flexible access control.

The linked version of Site is 2.0 and has a note that it is "not yet ready for evaluation outside of JUXT" but it is an evolution of Site 1.0 which is also based on XTDB and supports OpenAPI.

Pedestal

Another option for backend services is Pedestal, a sturdy and reliable base for services and APIs. It provides its own routing and interceptor-based approach to web development, but is based on Ring under the hood and uses Jetty 9 (currently an older 9.4.18, which is not the latest 9.4.x release). This was originally part of a full-stack project created by Relevance back in 2013 but can be used with various frontend options now.

Other Options

  • electric - a reactive Clojure dialect for web development that uses a compiler to infer the frontend/backend boundary
  • ripley - server rendered UIs over WebSockets.

Frontend Development

If you plan to use ClojureScript for the frontend of your web application, you again have a range of choices from "plain" ClojureScript up to various wrappers for React, and some other options.

Note: as a contributor to clojure-doc.org, I don't have enough experience to make recommendations about ClojureScript so I'm mostly just listing some options here -- Sean Corfield, 2023-10-09.

You will want to start with the ClojureScript Quick Start and then probably look at shadow-cljs as a build tool. An alternative build tool for ClojureScript is figwheel-main, but this seems to be less popular than shadow-cljs these days.

The creator of shadow-cljs has written a number of good articles about various approaches to using ClojureScript for frontend development, that show how to use "plain" ClojureScript without reaching for wrappers around JavaScript frameworks. Several frontend / full-stack options for ClojureScript wrap React.js in various ways but, as those articles show, building on top of React is not the only option!

UI-Focused Options

  • reagent - a minimalistic ClojureScript interface to React
  • re-frame - a functional reactive framework built on top of Reagent
  • helix - a simple, easy to use library for React development in ClojureScript
  • UIx - an idiomatic interface into modern React

While those are all based on or wrappers around React, there are other options:

  • hoplon - a ClojureScript library that unify some of the web platform's idiosyncrasies and present a fun way to design and build single-page web applications; hoplon builds on javelin which provides spreadsheet-like dataflow programming in ClojureScript

Full-Stack Options

  • fulcro - a library for development of single-page full-stack web applications in clj/cljs
  • sitefox - full-stack ClojureScript development on node.js

Producing JavaScript

Although ClojureScript (and thus all of the above Frontend Development options) produce JavaScript under the hood, there are times when you have an existing ecosystem based on HTML, CSS, and JavaScript and you want to add some ClojureScript to that. In that case, you can either use scittle, mentioned above or one of these ClojureScript to JavaScript compilers:

  • cherry - experimental ClojureScript to ES6 module compiler
  • squint - experimental ClojureScript syntax to JavaScript compiler

The former maintains ClojureScript semantics and syntax while the latter maintains only the syntax, compiling to JavaScript semantics. These projects can both be useful for adding ClojureScript components and modules to an existing JavaScript project.

See Also

Contributors

  • John Gabriele, Clinton Dreisbach (original authors)
  • Sean Corfield (2023 rewrite)