Life's too short to remember how to write Bash code. I feel liberated.
@laheadle on Clojurians Slack
Babashka is a native Clojure interpreter for scripting with fast startup. Its
main goal is to leverage Clojure in places where you would be using bash
As one user described it:
I’m quite at home in Bash most of the time, but there’s a substantial grey area of things that are too complicated to be simple in bash, but too simple to be worth writing a clj/s script for. Babashka really seems to hit the sweet spot for those cases.
- Fast starting Clojure scripting alternative for JVM Clojure
- Easy installation: grab the self-contained binary and run. No JVM needed.
- Familiar: targeted at JVM Clojure users
- Cross-platform: supports linux, macOS and Windows
- Interop with commonly used classes (
- Multi-threading support (
- Batteries included (tools.cli, cheshire, ...)
- Provide a mixed Clojure/Bash DSL (see portability).
- Replace existing shells. Babashka is a tool you can use inside existing shells like bash and it is designed to play well with them. It does not aim to replace them.
For installation options check Installation.
For quick installation use:
$ bash < <(curl -s https://raw.githubusercontent.com/babashka/babashka/master/install)
or grab a binary from Github
releases yourself and place it
anywhere on the path.
Then you're ready to go:
$ ls | bb -i '(filter fs/directory? *input*)'
("doc" "resources" "sci" "script" "src" "target" "test")
bb took 4ms.
You can support this project via Github
Ko-fi or indirectly via Clojurists
See companies for a list of companies using babashka.
Are you using babashka in your company or personal projects? Let us know
Babashka uses SCI for interpreting
Clojure. SCI implements a substantial subset of Clojure. Interpreting code is in
general not as performant as executing compiled code. If your script takes more
than a few seconds to run or has lots of loops, Clojure on the JVM may be a
better fit as the performance on JVM is going to outweigh its startup time
penalty. Read more about the differences with Clojure
java.lang can be considered stable
and is unlikely to change. Changes may happen in other parts of babashka,
although we will try our best to prevent them. Always check the release notes or
CHANGELOG.md before upgrading.
To get an overview of babashka, you can watch this talk (slides):
The babashka book contains detailed information
about how to get the most out of babashka scripting.
If you're a fan of Clojure for the Brave and
True, you might
enjoy Babashka Babooka, a book
by the same author, Daniel Higginbotham!
Read the output from a shell command as a lazy seq of strings:
$ ls | bb -i '(take 2 *input*)'
Read EDN from stdin and write the result to stdout:
$ bb '(vec (dedupe *input*))' <<< '[1 1 1 1 2]'
Read more about
*input* and in- and output flags
Execute a script. E.g. print the current time in California using the
(def now (java.time.ZonedDateTime/now))
(def LA-timezone (java.time.ZoneId/of "America/Los_Angeles"))
(def LA-time (.withZoneSameInstant now LA-timezone))
(def pattern (java.time.format.DateTimeFormatter/ofPattern "HH:mm"))
(println (.format LA-time pattern))
$ bb pst.clj
More examples can be found here.
You can try babashka online with Nextjournal's babashka notebook
Linux and macOS binaries are provided via brew.
brew install borkdude/brew/babashka
brew upgrade babashka
Linux and macOS (including ARM Macs) binaries are provided via nix (see the installation instructions for nix here).
# Adding `nixpkgs-unstable` channel for more up-to-date binaries, skip this if you already have `nixpkgs-unstable` in your channel list
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs-unstable
nix-env -iA nixpkgs-unstable.babashka
nix-env -iA nixpkgs-unstable.babashka
You can find more documentation on how to use babashka with nix here.
On Alpine it's recommended to download the binary manually from Github
Releases and use the static
babashka is available in the Arch User Repository. It can be installed using your favorite AUR helper such as
yay, yaourt, apacman and pacaur. Here is an example using
yay -S babashka-bin
asdf is an extendable version manager for linux and macOS.
Babashka can be installed using a plugin as follows:
asdf plugin add babashka https://github.com/pitch-io/asdf-babashka
asdf install babashka latest
On Windows you can install using scoop and the
Or just follow these concrete steps:
# Note: if you get an error you might need to change the execution policy (i.e. enable Powershell) with
# Set-ExecutionPolicy RemoteSigned -scope CurrentUser
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
scoop bucket add scoop-clojure https://github.com/littleli/scoop-clojure
scoop bucket add extras
scoop install babashka
If scoop does not work for you, then you can also just download the
binary from Github releases and
place it on your path manually.
Note: WSL1 users might experience a BSOD, please use the --static install option when installing
$ curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
$ chmod +x install
$ ./install --static
Install via the installer script for linux and macOS:
$ curl -sLO https://raw.githubusercontent.com/babashka/babashka/master/install
$ chmod +x install
By default this will install into
/usr/local/bin (you may need
this). To change this, provide the directory name:
$ ./install --dir .
To install a specific version, the script also supports
$ ./install --dir . --version 0.4.1
To force the download of the zip archive to a different directory than
$ ./install --dir . --version 0.4.1 --download-dir .
On Linux, if you want to install the static binary version:
$ ./install --dir . --version 0.4.1 --download-dir . --static
In case you want to check the download, you can use the
This maybe useful for unattended installations:
$ sha256sum babashka-0.4.1-linux-amd64-static.tar.gz
$ ./install --dir /tmp --checksum ab70fb39fdbb5206c0a2faab178ffb54dd9597991a4bc13c65df2564e8f174f6 --static --version 0.4.1
Note that the
--checksum option only works when
--version option is also
provided. This is to avoid breakage when a new version of Babashka is released.
You may also download a binary from
Github. For linux there is a
static binary available which can be used on Alpine.
- On Github Actions it's recommended to use setup-clojure with
- You can use the installer script on any non-Windows CI system. CircleCI requires
- On Appveyor + Windows you can use a bit of Powershell.
Check out the image on Docker hub.
Check out the news page to keep track of babashka-related news items.
Go here to see the full list of built-in namespaces.
A list of projects (scripts, libraries, pods and tools) known to work with babashka.
The babashka compatible badge indicates that a library can be used as babashka dependency.
If this is the case for your library, we encourage you to proudly display this badge.
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/badge.svg" alt="bb compatible" style="max-width: 100%;"></a>
The babashka built-in badge means that a library has been built directly into babashka and requires no extra dependencies to use it.
If this rare honor belongs to your library, you should display this badge.
<a href="https://babashka.org" rel="nofollow"><img src="https://github.com/babashka/babashka/raw/master/logo/built-in-badge.svg" alt="bb built-in" style="max-width: 100%;"></a>
Pods are programs that can be used as a Clojure library by
babashka. Documentation is available in the pod library
A list of available pods can be found in the pod registry.
Babashka is implemented using the Small Clojure
Interpreter. This means that a snippet or
script is not compiled to JVM bytecode, but executed form by form by a runtime
which implements a substantial subset of Clojure. Babashka is compiled to
a native binary using GraalVM. It comes with
a selection of built-in namespaces and functions from Clojure and other useful
libraries. The data types (numbers, strings, persistent collections) are the
same. Multi-threading is supported (
Differences with Clojure:
A pre-selected set of Java classes are supported. You cannot add Java classes
Interpretation comes with overhead. Therefore loops are slower than in Clojure
on the JVM. In general interpretation yields slower programs than compiled
definterface and unboxed math.
defrecord are implemented using multimethods and regular
maps. Ostensibly they work the same, but under the hood there are no Java
classes that correspond to them.
reify works only for one class at a time
clojure.core.async/go macro is not (yet) supported. For compatibility it
currently maps to
clojure.core.async/thread. More info
AWS Lambda runtime doesn't support signals, therefore babashka has to disable
handling of SIGINT and SIGPIPE. This can be done by setting
- Blambda analyses sites by Josh Glover
- The wizard of HOP - How we built the web based HOP CLI Settings Editor using Babashka and Scittle by Bingen Galartza
- Simple TUIs with Babashka and Gum by Rattlin.blog
- Babashka And Dialog Part Ii: Announcing The Bb-Dialog Library by A.C. Danvers
- Babashka Babooka: Write Command-Line Clojure by Daniel Higginbotham
- Re-Writing a GlobalProtect OpenConnect VPN Connect script in Babashka by Tory Anderson
- Babashka: How GraalVM Helped Create a Fast-Starting Scripting Environment for Clojure by Michiel Borkent (Japanese version here)
- Adding Prompts To Your Babashka Scripts With Dialog by A.C. Danvers
- Scraping an HTML dictionary with Babashka and Bootleg by exupero
- Using Babashka to Get Electricity Prices by Kari Marttila
- How to Do Things With Babashka by Paulus Esterhazy (2022-12)
- Using nREPL as a system interface by Dmitri Sotnikov
- Manage git hooks with babashka tasks by Mykhaylo Bilyanskyy
- Messing around with babashka by Ian Muge
- Introducing bbin by Radford Smith (2022-09)
- Deleting AWS Glacier vaults with babashka by Tim Zöller
- Recursive document transformations with Pandoc and Clojure by Teodor Heggelund
- Blambda! by Josh Glover
- Babashka CLI: turn Clojure functions into CLIs!
- Breakneck Babashka on K8s by Heow Goodman
- Recursive document transformations with Pandoc and Clojure
- Detecting inconsistent aliases in a clojure codebase by Oxalorg
- I, too, Wrote Myself a Static Site Generator by Daw-Ran Liou
- Babashka and Clojure by Rahul Dé at North Virginia Linux Users Group
- Create a password manager with Clojure using Babashka, sqlite, honeysql and stash by Daniel Amber
- Writing Clojure-living-cookbooks by Cyprien Pannier
- Using babashka with PHP by Michiel Borkent
- Moldable Emacs: a Clojure Playground with Babashka by Andrea
- Finding my inner Wes Anderson with #Babashka by Tim Zöller
- Awesome Babashka: Parse & produce HTML and SQLite by Jakub Holý
- Babashka tasks, talk by Michiel Borkent
- Rewriting a clojure file with rewrite-clj and babashka, video by Oxalorg
- Integrating Babashka into Bazel by Tim Jäger
- Talk: Babashka: a native Clojure interpreter for scripting — The 2021 Graal Workshop at CGO
- Blog: Playing New Music On Old Car Stereo With Clojure And Babashka
- Homoiconicity and feature flags by Martin Klepsch
- Clojure like its PHP by Jay Zawrotny (eccentric-j)
- Deploy babashka script to AWS Lambda by Dainius Jocas.
- Automating Video Edits with Clojure and ffmpeg by Adam James.
- Exporter for passwordstore.org by Eugen Stan
- Babashka and sci internals, a talk by Michiel Borkent at the London Clojurians Meetup.
- Writing Clojure on the Command Line with Babashka, a talk by Nate Jones.
- Using Clojure in Command Line with Babashka, a blog article by Kari Marttila.
- Babashka and GraalVM; taking Clojure to new places, a talk by Michiel Borkent at Clojure/NYC.
- Import a CSV into Kafka, using Babashka by Dave Martin
- Learning about babashka, a blog article by Andrew Montalenti
- Babashka Pods presentation by Michiel Borkent at the Dutch Clojure Meetup.
- AWS Logs using Babashka, a blog published by Toyokumo.
- The REPL podcast Michiel Borkent talks about clj-kondo, Jet, Babashka, and GraalVM with Daniel Compton.
- Implementing an nREPL server for babashka: impromptu presentation by Michiel Borkent at the online Dutch Clojure Meetup
- ClojureScript podcast with Jacek Schae interviewing Michiel Borkent
- Babashka talk at ClojureD (slides) by Michiel Borkent
- Babashka: a quick example by Malcolm Sparks
- Clojure Start Time in 2019 by Stuart Sierra
- Advent of Random
by Arne Brasseur
- Clojure in the Shell by Arne Brasseur
- Clojure Tool by Eric Normand
Before new libraries or classes go into the standardly distributed babashka
binary, these evaluation criteria are considered:
- The library or class is useful for general purpose scripting.
- Adding the library or class would make babashka more compatible with Clojure
libraries relevant to scripting.
- The library cannot be interpreted by with babashka using
- The functionality can't be met by shelling out to another CLI or can't be
written as a small layer over an existing CLI (like
- The library cannot be implemented as a
If not all of the criteria are met, but adding a feature is still useful to a
particular company or niche, adding it behind a feature flag is still a
possibility. This is currently the case for
next.jdbc and the
HSQLDB database drivers. Companies interested in these features can compile an
instance of babashka for their internal use. Companies are also free to make
forks of babashka and include their own internal libraries. If their customized
babashka is interesting to share with the world, they are free to distribute it
using a different binary name (like
etc.). See the feature flag documentation and the
implementation of the existing feature flags (example
Thanks to all the people that contributed to babashka:
Copyright © 2019-2020 Michiel Borkent
Distributed under the EPL License. See LICENSE.
This project contains code from:
- Clojure, which is licensed under the same EPL License.
Can you improve this documentation? These fine people already did:
Michiel Borkent, Arne Brasseur, Thiago Kenji Okada, Sameer Kolhar, Victor Bjelkholm, Rahuλ Dé, Graham Carlyle, Gomotso Lilokoe, sogaiu, Rovanion Luckey, Chowlz, Radford Smith, Édipo Féderle, Peter Nagy, Aleksandr Zhuravlёv, alimak17, Jeff Evans, Dainius Jocas, Nikita Prokopov, Søren Sjørup, Wes Morgan, Teodor Heggelund, Brett Rowberry, Eugen Stan, Martin Klepsch, c.p, Michael Wood, Marek J, LouD, Lee Read, Will, miclill, Sohalt, Peter Strömberg, Aleksander Madland Stapnes, Gabriel Horner, Nate Sutton, Bob, jess, David Harrigan & Andrea RichiardiEdit on GitHub