Conjure: a REPL client layer inside Neovim
Interactive evaluation for Neovim (Clojure, Fennel, Scheme, Python, JavaScript, PHP, R, Lua, Rust and more!)
At a glance
- What is it?
- Conjure puts an evaluation client for 21 languages into Neovim, one protocol core plus per language plugins. It is a good fit for Lisp work driven from the buffer, and a partial fit for anyone expecting the same features everywhere.
- Who is it for?
- Conjure earns its place for people who edit Lisp family code in Neovim and want evaluation without opening a second terminal. It does not suit anyone who needs one feature set across every language it lists, since coverage per client is uneven and the comparison table lives in the wiki rather than the repository.
- Can I use it commercially?
- Yes. Unlicense is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 13 days ago.
- What is it written in?
- Mainly Fennel, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 18, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Evaluation without leaving the buffer you are editing
Conjure describes itself as an interactive environment for evaluating code inside your running program. The problem it addresses is narrower than a full IDE bridge: you are editing a buffer in Neovim, and you want the form under your cursor sent to a live session and the result shown without leaving the editor. The README's own description of the workflow is that you send the right part of your code off for evaluation, see the results, wrap those results in more code and evaluate that again.
What you can send is broader than a single form. Mappings cover the current form, the file, the buffer, or the form sitting at a Neovim mark, which means a value you parked earlier in the session can be picked up later. The intended user is someone doing interactive development against a live program, not someone batching code and running a test suite. The payoff the project emphasises is not speed but context: actions and results are kept, so during a long bug hunt you do not have to remember what was evaluated and what came back.
One protocol core with per language client plugins
The core of Conjure is language agnostic, and the README states plainly that it is targeted at Lisps for now. Everything language specific sits in a client plugin, and each client picks its own transport. Clojure talks to a REPL over nREPL, with Babashka and Basilisp handled under the same umbrella. Janet goes either through spork/netrepl or over stdio, Racket over stdio, Hy over stdio, Scheme over stdio by default, Guile through a socket file, Common Lisp through Swank, Rust through evcxr, PHP through psysh, SQL through PostgreSQL psql and Ruby through irb. Fennel is the odd one out with two paths: inside Neovim via Lua and nfnl, or outside Neovim in any Lua process through a stdio REPL.
This split is the architecture in one line. A shared layer handles mappings, the result log and completion, while a client file knows how to start a process or open a socket, how to send code and how to parse what comes back. Help text follows the same split: `:help conjure` covers the core, and each client has its own topic under `:help conjure-client-{LANGUAGE}-{TRANSPORT}`, for example `:help conjure-client-clojure-nrepl`. That documentation split is a good sign, because it means the per language differences are meant to be read rather than guessed.
The result log buffer as working memory
Evaluation without a visible history is nearly useless, and Conjure's answer is a log buffer that keeps every result and can be opened at any time. This is the part of the design that matters most in practice. When you evaluate a form, get a value back, wrap it in more code and evaluate again, the chain of intermediate results stays reachable instead of scrolling away in a terminal.
The buffer also changes how debugging reads. The stated value is that the context is available when you are deep in a bug hunt, which is exactly when recalling which of twenty evaluations produced the odd value is hardest. Completeness is part of that story too: every result is kept rather than only the last one, so a wrong turn stays inspectable. If you have used a REPL where output replaced itself, the log buffer is the concrete difference you will notice first, not the mapping.
Trying Conjure before touching your Neovim config
You can run the interactive tutorial with only `curl` and an up to date `nvim`. This downloads the plugin, launches Neovim with `:ConjureSchool` already running, and then cleans up after itself, so nothing touches your configuration:
curl -fL conjure.oli.me.uk/school | shThat is the right first move, because the tutorial teaches the core principles and the mappings before you commit to a setup. Once you keep it, Neovim 0.10 or newer is the stated requirement. The installation section also points at Magic Kit, an opinionated starter kit that bundles Conjure with a wider configuration, which suits people who want a working environment rather than one plugin. The page does not print a plugin manager command in the text available here, so the exact install line has to come from that section or from `:help conjure`.
The repository's own container recipe shows the minimum shape of the environment. It installs a distribution Neovim and starts it directly:
FROM ubuntu:24.04
RUN apt-get install -y neovim
CMD nvimNote that the image installs Neovim from the distribution packages without pinning a version, while the documented requirement is 0.10 or newer. For a plugin whose per language clients attach to running processes and sockets, an old editor build in a dev container is a quiet source of failures.
Uneven client coverage across 21 languages
The language list is long, which makes it easy to read the project as uniformly capable. It is not. The README defers the real comparison to a wiki page, a comparison table for all clients and supported features, and that table is not reproduced in the repository. Which means the feature set for a given language is something you look up rather than something you can infer from the list.
The list itself already shows the seams. Counting the distinct languages named in the README gives 21. Lua is supported inside Neovim only, Fennel works both inside and outside, and most of the remaining entries are stdio only. Some languages, the README notes, such as Clojure, will connect to your REPL automatically, while others leave you to trigger the connection yourself with the given commands and mappings. The README is also careful that the core features are language agnostic but each client brings its own extra tools, so two users on the same plugin can have materially different workflows.
This is the honest limit of the project, and neither the README nor the client wiki page recorded in the repository describes a fallback. There is no partial support tier, no documented degradation path, and no rollback story for a client that turns out not to fit your language. Judge adoption per client, not per language name.
Autocompletion splits along deoplete and nvim-cmp
Conjure supports multiple asynchronous autocompletion frameworks, and the choice is a real fork in the road rather than a detail. deoplete is built in, and the traditional completion key also works:
<C-x><C-o>The other route is nvim-cmp with cmp-conjure, which the author says he actually recommends. The difference in approach is real: deoplete is a self contained completion source living inside the plugin, while nvim-cmp is an external framework that Conjure feeds through a separate adapter. The first is fewer moving parts and no extra dependency; the second gives you nvim-cmp's whole set of sources and behaviours, at the cost of a second plugin to install and configure. Evaluation, logging and mapping stay identical in both cases.
The same choice pattern runs through the rest of the project. Mapping prefixes are configurable rather than fixed, and the core client layer is designed so that a language nobody has written yet can be added by someone else. That openness is a genuine strength, and it is also why you have to check the client table yourself.
Packaging metadata that contradicts the repository
A close look at the root of the repository turns up metadata that does not match the project around it. `package.json` declares version 1.0.0 and license ISC, and points its main entry at index.js, yet the repository ships an UNLICENSE file and the most recent tag is v4.60.0. No index.js appears among the top level entries either. The only declared dependency is a development one, shadow-cljs at ^2.8.97, which fits a JavaScript toolchain used to build the Neovim plugin rather than an npm package meant for consumption. The Dockerfile additionally carries commented out lines for nodejs, npm, typescript, ts-node and picolisp, so container based experimentation on other languages is a stub someone started and left.
The test script in that same file is a placeholder that exits with an error, while the repository also carries tests.edn, project.clj, deps.edn, a .fs.test entry and a scripts directory. The gap between a 1.0.0 manifest and a v4.60.0 tag is the kind of thing that makes automated dependency scanners report this repository as something it is not. The JavaScript and ClojureScript build files, shadow-cljs.edn, and the Fennel sources in fnl/ alongside the compiled lua/ directory explain the shape: this is a Fennel and ClojureScript project that compiles down to Lua and Neovim modules, with the manifest left over from the build tooling. The repository is not archived and its last push was on 2026-09-25.
The practical consequence for an adopter is small but worth stating: read package.json as build tooling residue rather than as the authoritative statement of terms or version, and take those from the UNLICENSE file at the root and from the tag list instead.
Editorial conclusion
Conjure earns its place for people who edit Lisp family code in Neovim and want evaluation without opening a second terminal. It does not suit anyone who needs one feature set across every language it lists, since coverage per client is uneven and the comparison table lives in the wiki rather than the repository. Before adopting, open `:help conjure-client-{LANGUAGE}-{TRANSPORT}` for your language and read what that client actually gives you. Then confirm `:ConjureSchool` runs inside your own configuration on Neovim 0.10 or newer before adding any client-specific mappings.
Frequently asked questions
What does Conjure require before it will work in Neovim?
Neovim 0.10 or newer. You can also trial it with only curl and an up to date nvim using the tutorial script, which downloads the plugin temporarily and cleans up after itself.
How do I evaluate the form under my cursor in Conjure?
With `<prefix>ee`, where `<prefix>` defaults to `<localleader>`. You can set your own `<localleader>` or configure Conjure to use a different prefix, documented under `:h g:conjure#mapping#prefix`.
Which completion engines can Conjure feed?
deoplete is built in and `<C-x><C-o>` also works. You can instead use nvim-cmp with cmp-conjure, which the README says the author actually recommends.
Where do I find the mappings and config for a specific language?
`:help conjure` covers the core, and each client has its own topic such as `:help conjure-client-clojure-nrepl`. `:ConjureSchool` runs an interactive tutorial of the core principles and mappings.
Does Conjure support the same features for every language?
No. The core features are language agnostic, but each client provides its own extra tools, so coverage differs per language. The full comparison lives in a wiki table of clients and supported features, and some transports are specific, such as Fennel inside Neovim versus Fennel over stdio outside it.
Official sources
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.
[](https://hysenlabs.com/projects/olical-conjure)