2 minute read

(defproject little_ring_things "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :min-lein-version "2.0.0"
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [compojure "1.6.1"]
                 [ring/ring-defaults "0.3.2"]]
  :plugins [[lein-ring "0.12.5"]]
  :ring {:handler little-ring-things.handler/app}
  :profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring/ring-mock "0.3.2"]]}})

This is a Leiningen project definition file (project.clj) for a Clojure web application. Leiningen is the standard build tool for Clojure, similar to Maven for Java or npm for Node.js. Let me break it down piece by piece.


Top-Level Declaration

(defproject little_ring_things "0.1.0-SNAPSHOT"

defproject is a Leiningen macro that defines the project. It takes two required arguments:

  • little_ring_things — the project name (artifact ID). Note the underscore; Clojure conventionally uses hyphens in namespaces, but the project name here uses underscores (a common Leiningen quirk).
  • "0.1.0-SNAPSHOT" — the version string. SNAPSHOT is a Maven convention meaning this is a work-in-progress, not a stable release. It signals to build tools that this artifact may change.

Metadata Fields

:description "FIXME: write description"
:url "http://example.com/FIXME"

These are placeholder strings auto-generated by lein new. They’re purely informational, used when publishing to a repository like Clojars. The FIXME comments are reminders to fill them in.

:min-lein-version "2.0.0"

Enforces a minimum Leiningen version. If someone tries to build this project with Leiningen older than 2.0.0, they’ll get an error. This guards against incompatible older tooling.


Dependencies

:dependencies [[org.clojure/clojure "1.10.0"]
               [compojure "1.6.1"]
               [ring/ring-defaults "0.3.2"]]

These are the runtime dependencies, specified as [group-id/artifact-id "version"] vectors — standard Maven coordinate notation.

  • org.clojure/clojure "1.10.0" — Clojure itself is an explicit dependency, which is unusual compared to most languages. This pins the exact Clojure version the project runs on.

  • compojure "1.6.1" — A routing library for Clojure. It lets you define URL routes concisely, mapping HTTP methods and paths to handler functions. Think of it as the equivalent of Express.js routes or Flask’s @app.route.

  • ring/ring-defaults "0.3.2" — Ring is Clojure’s foundational web library (analogous to WSGI in Python or Rack in Ruby). ring-defaults specifically provides pre-configured middleware stacks — sensible default settings for things like session handling, cookies, security headers, and parameter parsing — so you don’t have to wire them up manually.


Plugins

:plugins [[lein-ring "0.12.5"]]

Plugins extend Leiningen itself with new tasks. lein-ring adds Ring-specific commands:

  • lein ring server — starts a development web server with auto-reload
  • lein ring uberjar — packages the app as a standalone JAR
  • lein ring uberwar — packages it as a WAR file for servlet containers

Ring Configuration

:ring {:handler little-ring-things.handler/app}

This tells lein-ring where the entry point of the web application is. little-ring-things.handler/app refers to a Var named app in the namespace little-ring-things.handler — this would be the root Ring handler function (or a wrapped middleware chain) that receives every incoming HTTP request.


Profiles

:profiles
  {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
                        [ring/ring-mock "0.3.2"]]}}

Profiles allow environment-specific configuration. The :dev profile adds dependencies that are only needed during development and testing — they won’t be included in a production build:

  • javax.servlet/servlet-api "2.5" — The Java Servlet API. Required to run an embedded servlet container locally during development (Jetty, which lein-ring uses under the hood, needs it).

  • ring/ring-mock "0.3.2" — A testing utility that lets you construct fake HTTP requests to pass directly to your Ring handlers, so you can test them without spinning up an actual server.


Summary

In plain terms, this file describes a minimal Clojure web app that uses Ring as its HTTP abstraction layer and Compojure for routing. It’s the kind of scaffolding you’d get from running lein new compojure little-ring-things — a starting point for building a small web service or API.

Updated: