An nREPL client/server library for the Janet programming language
janet janet-lang nrepl
0

Configure Feed

Select the types of activity you want to include in your feed.

Janet 100.0%
Other 0.1%
13 1 0

Clone this repository

https://tangled.org/tomwaddington.dev/nrepl-janet https://tangled.org/did:plc:ezteglpj5un4imwiakz2f64k
git@tangled.org:tomwaddington.dev/nrepl-janet git@tangled.org:did:plc:ezteglpj5un4imwiakz2f64k

For self-hosted knots, clone URLs may differ based on your setup.



README.md

nrepl-janet#

An nREPL client/server library for the Janet programming language.

nREPL is a language-agnostic, message-oriented network REPL protocol from the Clojure community. A conforming nREPL server lets Janet plug into the existing ecosystem of nREPL clients and editor integrations. This library speaks the standard bencode-over-socket nREPL wire protocol.

Demo#

An asciinema recording of interacting with nrepl-janet in Helix via nrepl.hx

Interacting with an nrepl-janet server via nrepl.hx in Helix.

Status#

Working server covering the operations editors depend on:

Op Notes
clone new session, optionally inheriting another session’s env
close cancel any running eval and tear the session down
describe advertises supported ops + versions
eval form-by-form, streaming out/err, one value per form
load-file evaluate file contents with a source name for error locations
interrupt ev/cancel the running eval (cooperative — see caveat)
ls-sessions list active sessions
lookup doc / arglists / source location for a symbol
completions prefix completion over the session’s bindings
stdin feed input to a blocked read (see stdin caveat)

Interrupt caveat: cancellation is cooperative. ev/cancel only takes effect when the evaluation yields to the event loop (I/O, ev/sleep, channel ops).

Stdin caveat: input is read through getline, which is shadowed during evaluation to emit need-input and wait for a stdin op. Janet’s real getline reads the server process’s blocking C stdin, which can’t signal need-input and would stall the single-threaded event loop — so code that reads input via other means (e.g. (file/read stdin :line)) is not redirected. An empty stdin payload signals end-of-input.

Installation#

Either packaging system works; both read the package name and dependencies from the same project.janet.

jpm install            # via the Janet Project Manager
janet --install .      # via Janet’s built-in bundle system

spork must already be on the Janet syspath before installing. It’s both a runtime dependency and (for janet --install) a build-time one. Install it the same way first if needed: janet --install https://github.com/janet-lang/spork.git.

Usage#

(import nrepl)

# Block until the listener is closed:
(nrepl/run-server "127.0.0.1" "7888")

# Or run non-blocking and keep the returned listener to stop later:
(def listener (nrepl/server "127.0.0.1" "7888"))
# ... later ...
(:close listener)

Defaults are 127.0.0.1:7888.

Starting from the shell (jack-in)#

Once installed, a one-liner that blocks on the listener, suitable for editor jack-in, with the host/port baked into the launched command:

janet -e '(import nrepl)(nrepl/run-server "127.0.0.1" "7888")'

Talking to it from Janet#

A minimal client ships for testing and quick poking:

(import nrepl)
(def c (nrepl/connect "127.0.0.1" "7888"))

(def session
  (-> (nrepl/request c {:op "clone" :id "1"})
      (first)
      (get :new-session)))

(nrepl/request c {:op "eval" :id "2" :session session :code "(+ 1 2)"})
# => @[@{:value "3" :ns "user" ...} @{:status @["done"] ...}]

License#

Copyright © 2026 Tom Waddington

Distributed under the MIT License. See LICENSE file for details.