Library / SDK
bhauman/rebel-readline avatar
bhauman/rebel-readline

rebel-readline: a real line editor for the Clojure REPL

Terminal readline library for Clojure dialects

747 stars40 forksClojureEPL-1.0

At a glance

What is it?
Rebel Readline replaces the plain Clojure REPL with a JLine-based editor that does multi-line editing, auto-indent, tab completion and inline evaluation, and it also ships as a reusable line reader library. The catch is that it needs direct terminal access, so it cannot run under the usual clj wrapper.
Who is it for?
Adopt rebel-readline if you spend your day in a Clojure REPL and the stock reader is costing you, since the editing, completion and inline evaluation are real improvements, and the same line reader is available as a library for Clojure dialects. Keep away if your REPL has to start through clj or rlwrap, because the line reader requires direct terminal access and conflicts with other readline processes.
Can I use it commercially?
Yes, with conditions. EPL-1.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 125 days ago.
What is it written in?
Mainly Clojure, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The REPL you get, and the library underneath it

Rebel Readline is a terminal readline library for Clojure dialects, and it is two things at once. It is a Clojure REPL with a proper line editor, and it is a library that provides a line reader for Clojure dialects.

The REPL features are the list you would expect from a modern editor. There is easy multi-line editing and auto-indentation, TAB completion, and argument documentation displayed after you type a function name. There is inline evaluation, which lets you evaluate code without pressing enter. There is quick access to documentation, source and apropos for the symbol under the cursor. And the familiar terminal key bindings, including history search.

The library half is the more reusable part, and the one that matters if you are building a tool rather than just using a REPL. If you are writing something that reads a line from a user, that is the piece to reach for, and the fact that it supports Clojure dialects rather than only Clojure suggests the core is portable.

There is also a Paredit integration, a separate rebel-readline-paredit directory, which is the kind of thing that would be a large feature to reimplement and an obvious one to want once you have structural editing in a Clojure REPL.

The project is EPL-1.0 licensed, the default branch is master, and the last push was on 2026-06-20. The release list shows 0.1.3 in May 2018 with improved completion and faster startup, 0.1.4 in June 2018 fixing large value printing, and 0.1.5 in February 2025 adding nREPL support. There is a separate ClojureScript package and a separate nREPL package, each with its own Clojars badge.

One version detail to notice before you install anything. The installation instructions throughout the README refer to version 0.1.11, while the newest listed release is 0.1.5, so the README is describing a version that is not in the release list.

The terminal access rule, and how to launch it anyway

There is one instruction in this project that people hit immediately, and the README calls it an important note.

The line reader requires direct terminal access. Therefore, do not launch Rebel Readline using clj or any other readline processes like rlwrap, to avoid conflicts. Instead you start the JVM one of four ways: the java command, the Clojure clojure tool without readline support, lein trampoline, or boot, which must run in Boot's worker pod.

That is the entire cost of the tool in one paragraph. A Clojure developer who has spent years typing clj at the prompt has to change the muscle memory to clojure, and the reason is that two things cannot both own the terminal's line editing, which is exactly what a readline library does and what rlwrap also does.

The quick start is a single command with the dependency inline:

shell
clojure -Sdeps "{:deps {com.bhauman/rebel-readline {:mvn/version \"0.1.11\"}}}" -M -m rebel-readline.main

Installing it as a tool from the latest Git release tag uses the tools installer:

shell
clojure -Ttools install-latest :lib com.github.bhauman/rebel-readline :coord '{:git/url "https://github.com/bhauman/rebel-readline.git" :deps/root "rebel-readline"}' :as rebel

and after that you launch it from a project directory with:

shell
clojure -Trebel repl

The permanent installation route is an alias in your ~/.clojure/deps.edn, and the README is explicit that you then use clojure rather than clj, to avoid interference from other readline tools.

Key bindings, and the commands that extend it

The REPL defaults to Emacs-style key bindings, which can be configured, and the documented ones are worth listing because they are the reason to switch.

Ctrl-C aborts the current line, and Ctrl-D at the start of a line sends an end-of-stream signal, which usually quits the REPL. TAB does word completion or code indentation depending on context. Then there is a cluster of four on Ctrl-X: Ctrl-X Ctrl-D shows documentation for the current symbol, Ctrl-X Ctrl-S shows source code for it, Ctrl-X Ctrl-A shows apropos information for it, and Ctrl-X Ctrl-E is inline evaluation for an SEXP.

The Ctrl-X prefix cluster is the design detail. Doc, source, apropos and inline evaluation are the four things you want on the symbol under the cursor, and putting them behind one prefix keeps the plain Ctrl keys free for editing.

The commands are namespaced with :repl/, and you can list them by typing :repl/help or :repl followed by TAB. You can add your own by implementing methods for the rebel-readline.commands/command multimethod and documenting them with rebel-readline.commands/command-doc, which is a clean extension point: a command is a multimethod method, and the documentation is a separate function so a command can have a doc string without the implementation knowing about it.

There is a :repl/key-bindings command for exploring the full set of bindings, so the documented list is the interesting subset rather than the complete one.

Configuration, the CLI switches, and vi bindings

Configuration lives in an EDN file, either in your deps.edn or in ~/.clojure/rebel_readline.edn, and the options are a small set.

The :config key is a path to an EDN configuration file. The :key-map key is :viins or :emacs, defaulting to :emacs. The :color-theme key is a screen theme, with :light, :dark and :neutral. The :highlight key is a boolean for syntax highlighting, and there are more options beyond the part of the list that is visible here.

Settings can be passed on the command line too. The README shows passing a parameter when launching the REPL:

shell
clojure -Xrebel :highlight false 

and the same parameters can be specified in the :exec-args key of your deps.edn, which is the difference between a one-off override and a permanent one.

The main entry point has its own command line, and the help output is a good summary of what can be turned off:

shell
Options:
  -h, --help                                       Display help
  -k, --key-map KEYMAP         :emacs              Choose between :viins or :emacs
  -t, --color-theme THEME      :dark-screen-theme  :(light, dark, or neutral)-screen-theme
      --no-highlight                               Disable syntax highlighting
      --no-completion                              Disable code completion
      --no-eldoc                                   Disable function documentation display
      --no-indent                                  Disable auto indentation
      --no-redirect-output                         Disable output redirection
  -b, --key-bindings BINDINGS                      Specify custom key bindings
  -c, --config CONFIG                              Path to a config file

Every visible feature has a switch to turn it off, which matters on a slow connection over SSH where highlighting and eldoc are the first things people turn off. Custom key bindings and a config file path are there too.

For vi users, the key map is set with a single option:

clojure
{:key-map :viins}

and the README notes you can put that in your deps.edn or in the same rebel_readline.edn file as the other options.

Java 22, nREPL, and the other build tools

Two environment issues are worth planning for.

The first is Java 22. On Java 22 and later, Rebel Readline can show a native access warning from JLine or one of its terminal support libraries. The warning does not mean Rebel Readline failed to start, and to suppress it you pass a JVM option:

shell
clojure -J--enable-native-access=ALL-UNNAMED -Sdeps "{:deps {com.bhauman/rebel-readline {:mvn/version \"0.1.11\"}}}" -M -m rebel-readline.main

In a tools.deps alias you add the option to :jvm-opts, alongside the extra dependency and the main options:

clojure
:aliases
{:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.11"}}
         :main-opts ["-m" "rebel-readline.main"]
         :jvm-opts ["--enable-native-access=ALL-UNNAMED"]}}

The second is nREPL. Recent updates include nREPL support, with the details in the rebel-readline-nrepl directory, and that is a separate Clojars package. That matters if your workflow is an nREPL-based editor rather than a terminal, since the terminal REPL and the nREPL are different ways to reach the same line reader.

The other build tools are supported too, with an alias in deps.edn pointing at a tool, and a launch that uses the exec-fn:

clojure
{
 ...
 :aliases {:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.11"}}
                   :exec-fn rebel-readline.tool/repl
                   :exec-args {}
                   :main-opts ["-m" "rebel-readline.main"]}}
 ...
}

and then:

shell
clojure -Xrebel 

Leiningen has its own route, with the dependency in project.clj and a trampoline launch:

clojure
[com.bhauman/rebel-readline "0.1.11"]
shell
lein trampoline run -m rebel-readline.main

which can also be added to your Leiningen profiles so you do not have to touch individual projects, and turned into an alias so that lein rebl starts the REPL. Boot is the third option:

shell
boot -d com.bhauman/rebel-readline call -f rebel-readline.main/-main

with the note that it must run in Boot's worker pod, which is the same direct terminal access rule again.

Where rebel-readline is the wrong choice

The first wrong case is a team whose REPL has to start through clj. The restriction is absolute and it is not negotiable from the configuration, so if your tooling, your container entrypoint or your muscle memory all say clj, this tool cannot be used without changing one of them. That is a small thing for one developer and a coordination problem for a team.

The second is a workflow that is not a terminal at all. A ClojureScript workflow, an editor-driven nREPL session or a remote execution environment has no terminal to own, and the whole value of the tool is the terminal editing. The nREPL package exists for the editor case, but then the terminal REPL features are not what you are using.

The third is a shared or CI environment. The line reader needs direct terminal access, so it does not belong in a non-interactive script, and in CI you want the plain clojure.main REPL or a script, not an editor.

The fourth is a project that has standardised on a different REPL enhancement. tools.deps, Leiningen and Boot all have their own REPL setups, and the Paredit support here is one more thing to learn.

The alternative worth weighing is the plain clojure.main REPL with clj, which is slower and less capable but starts everywhere and needs no configuration. There is also the option of using a modern editor with a Clojure LSP, which gives you structured editing and inline evaluation without owning the terminal at all, at the cost of a heavier setup. The Rebel Readline case is the developer who wants terminal editing with a real editor's features and is willing to change one command.

Editorial conclusion

Adopt rebel-readline if you spend your day in a Clojure REPL and the stock reader is costing you, since the editing, completion and inline evaluation are real improvements, and the same line reader is available as a library for Clojure dialects. Keep away if your REPL has to start through clj or rlwrap, because the line reader requires direct terminal access and conflicts with other readline processes. Before you switch, read the Java 22 note, because you will need the native access flag to silence a JLine warning, and check that the version you pin is the one your tooling expects, since the README uses 0.1.11 while the latest listed release is 0.1.5.

Frequently asked questions

What does rebel-readline add to the Clojure REPL?

Multi-line editing, auto-indentation, TAB completion, argument documentation shown after typing a function name, inline evaluation without pressing enter, and quick access to documentation, source and apropos for the symbol under the cursor, with familiar terminal key bindings including history search.

How do I start rebel-readline?

You must give it direct terminal access, so use clojure rather than clj and avoid rlwrap. The quick start is clojure -Sdeps with the dependency inline and -M -m rebel-readline.main, or install it as a tool with clojure -Ttools install-latest and then launch it with clojure -Trebel repl. Leiningen and Boot are also supported.

What is the Java 22 native access warning about?

On Java 22 and later, JLine or one of its terminal support libraries can show a native access warning. It does not mean Rebel Readline failed to start, and you silence it by passing the JVM option --enable-native-access=ALL-UNNAMED, either on the command line with -J or in a tools.deps alias under :jvm-opts.

Can I use vi key bindings in rebel-readline?

Yes. The key map is set to :viins, either in your deps.edn or in ~/.clojure/rebel_readline.edn, with the setting {:key-map :viins}. You can also pass it on the command line with the key-map option, and the default is :emacs.

Official sources

  1. bhauman/rebel-readline on GitHub
  2. Issues
  3. License: EPL-1.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/bhauman-rebel-readline.svg)](https://hysenlabs.com/projects/bhauman-rebel-readline)

Was this useful?