Skip to content

abogoyavlensky/slim

Repository files navigation

slim

Clojars Project cljdoc badge CI

The slim way to build Clojure.

Overview

slim is a build tool for Clojure projects that emphasizes simplicity and minimal configuration. It helps you build uberjars for applications or build and deploy jars for libraries with zero ceremony.

Features

  • 🔄 Versatile Building: Can build applications (uberjar), and build and deploy libraries
  • 🎯 Minimal Configuration: Uses deps.edn - no additional configuration files needed
  • 🔧 Sensible Defaults: Works out of the box with minimal configs for most Clojure projects
  • 📦 Minimal Dependencies: Built on top of tools.build and slipset/deps-deploy

Quick Start: Build App

Add slim to your deps.edn:

{:aliases
 {:slim {:deps {io.github.abogoyavlensky/slim {:mvn/version "LATEST"}}
         :ns-default slim.app
         :exec-args {:main-ns my-app.core}}}}

Run the build:

clojure -T:slim build

That's it! Your uberjar will be created at target/standalone.jar.

Motivation

Using bare tools.build and slipset/deps-deploy isn't particularly difficult - you only need a few lines in build.clj and an alias in deps.edn. However, you have to write this build script for each project repeatedly. In practice, these scripts are quite similar when building jars, yet I found myself writing them over and over.

There are other existing build tools for Clojure, such as build.edn and Clein (links below). These tools are excellent, offering flexibility and rich features. However, this flexibility comes with the cost of extensive configuration: either through a separate file (build.edn), a separate alias (Clein), or verbose configuration (both). For most projects, this level of complexity isn't necessary, as they don't require such extensive flexibility. Additionally, both tools primarily focus on building and deploying libraries, whereas I wanted a versatile tool capable of handling both applications and libraries.

The main motivation behind Slim, and the answer to "Why one more build tool?" is to make the build process for Clojure projects as effortless and minimal as possible. Most projects can be configured with just one parameter for applications and two parameters for libraries. I aimed to streamline the building/deploying process to be as smooth as possible. At its core, Slim requires just one alias and a few required options to manage essential tasks. I designed Slim to be a very thin wrapper around tools.build, adding helpful utilities in a more user-friendly way, with sensible defaults and assumptions. At the same time, it maintains the flexibility to configure virtually any aspect of the build process.

Usage

Build: App

Builds an uberjar file for an application. The minimal configuration requires only the main namespace:

{:aliases
 {:slim {:deps {io.github.abogoyavlensky/slim {:mvn/version "LATEST"}}
         :ns-default slim.app
         :exec-args {:main-ns my-app.core}}}}

Available commands

Command Description
build Builds an uberjar file with all dependencies included. The uberjar file will be created at the specified location (defaults to target/standalone.jar).

Custom configuration

You can customize the build with optional parameters. All available options are shown below:

{...
 :exec-args {:main-ns my-app.core
             :target-dir "custom-target"
             :uber-file "my-app.jar"
             :src-dirs ["src" "resources" "custom-src"]
             :class-dir "custom-classes"}}
  • :main-ns (required) - Main namespace to compile.
  • :target-dir (optional) - Target directory for build artifacts (default: "target").
  • :uber-file (optional) - Name of the output uberjar (default: "target/standalone.jar").
  • :src-dirs (optional) - Source directories to include (default: ["src" "resources"]).
  • :class-dir (optional) - class directory (default: "target/classes").

Build: Library

Builds and deploys a jar file for a library. The minimal configuration requires the library name and version. It also requires the slipset/deps-deploy dependency to deploy the library to Clojars:

{:aliases
 {:slim {:deps {io.github.abogoyavlensky/slim {:mvn/version "LATEST"}
                slipset/deps-deploy {:mvn/version "0.2.2"}}
         :ns-default slim.lib
         :exec-args {:lib my-org/my-lib
                     :version "0.1.0"}}}}

Install locally:

clojure -T:slim install

Run the build and deploy snapshot version:

clojure -T:slim deploy :snapshot true

or deploy release version:

clojure -T:slim deploy

That's it! Your library has been built and deployed to Clojars.

Important

You need to have CLOJARS_USERNAME and CLOJARS_PASSWORD environment variables set to your Clojars credentials.

Available commands

Command Description Options
build Builds a jar file for the library. :snapshot (optional) - If true, the jar will be built as a snapshot version. Default is false.
install Builds and installs the jar to local Maven repository. :snapshot (optional) - If true, the jar will be installed as a snapshot version. Default is false.
deploy Builds and deploys the jar to Clojars (requires CLOJARS_USERNAME and CLOJARS_PASSWORD environment variables). :snapshot (optional) - If true, the jar will be deployed as a snapshot version. Default is false.
tag Creates a git tag for the library version. :push - If true automatically pushes the newly created git tag to remote repository. Default is false.

Extended configuration

You can customize the build with optional parameters for extended metadata information in the library's pom-file.

{...
 :exec-args {:lib my-org/my-lib
             :version "0.1.0"
             :url "https://github.com/my-org/my-lib"
             :description "My awesome library"
             :developer "Your Name"}}
  • :lib (required) - Library name in org/lib format.
  • :version (required) - Library version. The version will be used as a git tag as-is. If you want to customize it, please use the :scm option.
  • :url (optional) - Project URL. It will also be used as the SCM URL if option :scm-url is not set.
  • :scm-url (optional) - Repository URL. If not set, defaults to :url.
  • :description (optional) - Project description.
  • :developer (optional) - Developer name.
  • :license (optional) - If not set, defaults to: {:name "MIT License" :url "https://opensource.org/license/mit"}.

Custom configuration

The options :url, :description, :developer, and :license are used to generate the pom-file for the library. If you need to customize the pom-file, you can pass the :pom-data option, which will take precedence over other options. An example of :pom-data:

{...
 :exec-args {...
             :pom-data [[:description "My awesome library"]
                        [:url "https://github.com/username/lib"]
                        [:licenses
                         [:license
                          [:name "MIT License"]
                          [:url "https://opensource.org/license/mit/"]]]
                        [:developers
                         [:developer
                          [:name "Person Name"]]]]}}

By default, :scm is generated using :url (or :scm-url) and :version (as tag). If :snapshot is true, the tag will be presented as latest git commit hash. This is useful for Cljdoc, which requires a unique version for each build, and it allows you to preview doc for each snapshot. If you need to customize your SCM repository data, you can pass the :scm option with a value:

{...
 :exec-args {...
             :scm {:url "https://github.com/username/lib"
                   :connection "scm:git:git://github.com/username/lib.git"
                   :developerConnection "scm:git:ssh://[email protected]/username/lib.git"
                   :tag "v0.1.0"}}}

Tip

For other options, please consult the spec of the library and the definition of clojure.tools.build.api/write-pom function.

Examples

Inspired by

Alternatives

License

MIT License Copyright (c) 2025 Andrey Bogoyavlenskiy