Getting started with nREPL server and REPL-y client

nREPL

If you are using Clojure, you might be interested in nREPL which lets you connect a REPL terminal to a running Clojure program. In the following howto I am setting up a small nREPL demo using the nREPL server and the REPL-y nREPL client.

First I set up aliases for the server and client in $HOME/.clojure/deps.edn as follows:

{:aliases {:nrepl {:extra-deps {nrepl/nrepl {:mvn/version "1.1.0"}}}
           :reply {:extra-deps {reply/reply {:mvn/version "0.5.1"}}
                   :main-opts ["-m" "reply.main" "--attach" "7888"]}}}

Now I need a small demo program to test things out. First I create $HOME/Documents/repltest/deps.edn which just specifies the Clojure version.

{:deps {org.clojure/clojure {:mvn/version "1.11.1"}}
 :paths ["src"]}

The following program then displays a counter which gets increased once per second. Furthermore it starts an nREPL server on port 7888. The program goes into the file $HOME/Documents/repltest/src/repltest/core.clj.

(ns repltest.core
  "nREPL demo"
  (:gen-class))

(require '[nrepl.server :refer [start-server stop-server]])
(defonce server (start-server :port 7888))

(def t (atom 0))

(defn display
  [value]
  (println value))

(defn -main
  "nREPL demo"
  [& _args]
  (while true
         (display (swap! t inc))
         (Thread/sleep 1000))
  (System/exit 0))

Now one can run the program using clj -M:nrepl -m repltest.core. The program will print out consecutive numbers as follows:

1
2
3
4
.
.
.

Now you need to open a second terminal for the nREPL client. You run the network client using clojure -M:reply. The important thing which took me some time to find out is that you need to then switch to your applications namespace as follows:

user=> (ns repltest.core)

Now you can easily access the variables of the main program:

repltest.core=> @t
42

You can also modify the value while the main program is still running:

repltest.core=> (swap! t - 10)
32

You should see the counter decrease in the application’s output.

You can even redefine the display methods using the nREPL client. I.e. you can do interactive development.

repltest.core=> (defn display [value] (println "value =" value))

The program output will now be modified as follows:

value = 32
value = 33
value = 34
.
.
.

See github.com/wedesoft/repltest for the demo code.

Enjoy!