Library / SDK
Vigemus/iron.nvim avatar
Vigemus/iron.nvim

iron.nvim: Interactive REPL Integration for Neovim as Both Plugin and Library

Interactive Repl Over Neovim. What is iron.nvim Iron allows you to quickly interact with the repl without having to leave your work buffer It both a plugin and a library, allowing for better user experience and extensibility at the same time.

1,364 stars111 forksLuaBSD-3-Clause

At a glance

What is it?
iron.nvim is a BSD-3-Clause licensed Neovim plugin and library that embeds interactive REPL sessions into splits or floating windows, with configurable per-language REPL definitions and a library API that plugin authors can extend.
Who is it for?
iron.nvim is the right tool for Neovim users who work interactively with interpreted languages, particularly Python, R, Haskell, or any language with a REPL, and want to send code from their editor buffer directly to the interpreter without switching terminals. The scratch_repl option and customizable window placement make it adaptable to different workflow preferences.
Can I use it commercially?
Yes. BSD-3-Clause 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 15 days ago.
What is it written in?
Mainly Lua, according to GitHub's language statistics.

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

Editorial analysis

What iron.nvim provides and who uses it

A REPL (read-eval-print loop) is an interactive programming environment where code is sent, evaluated immediately, and results are returned line by line. Data scientists, language learners, and exploratory programmers rely on REPLs heavily: Python's interpreter, R's console, IPython, GHCi for Haskell, and dozens of others all operate as REPLs.

iron.nvim brings the REPL into Neovim without requiring you to switch to a terminal emulator. The README describes its goal directly: iron allows you to quickly interact with the REPL without having to leave your work buffer. Code in the editor buffer is sent to the REPL with a keymap; the REPL output appears in an adjacent split or floating window. The buffer and the REPL window stay open simultaneously.

The plugin's secondary identity as a library is significant. iron.nvim exposes an API that other plugins can use to build on top of its REPL management, rather than each plugin reinventing REPL lifecycle handling independently. This is a design decision that distinguishes iron.nvim from simpler send-to-terminal plugins.

The plugin requires Neovim and its Lua API. It does not support Vim. The BSD-3-Clause licence permits use, modification, and redistribution with minimal restrictions.

Configuring REPL definitions per language

iron.nvim lets you define the REPL command for each language separately. The configuration is passed to `iron.setup` under the `repl_definition` key. A simple shell definition looks like this:

lua
local iron = require("iron.core")
local view = require("iron.view")
local common = require("iron.fts.common")

iron.setup {
  config = {
    scratch_repl = true,
    repl_definition = {
      sh = {
        command = {"zsh"}
      },
      python = {
        command = { "python3" },
        format = common.bracketed_paste_python,
        block_dividers = { "# %%", "#%%" },

The `command` field accepts a table of strings that maps to the shell command to launch the REPL. For Python, the README also shows `{ "ipython", "--no-autoindent" }` as an alternative to `python3`. The `format` field applies a specific text format before sending code to the REPL; `common.bracketed_paste_python` uses Python's bracketed paste mode, which handles multi-line code blocks correctly.

The `block_dividers` field defines markers that iron.nvim uses to identify code cells in the buffer, similar to Jupyter notebook cell separators. The `# %%` and `#%%` markers allow sending an entire cell to the REPL in one operation.

Dynamic REPL commands with a function

The `command` field in a REPL definition can be a function rather than a static table. This allows the REPL command to be computed at the time the REPL is opened rather than at configuration time. The README shows a Haskell example where the REPL command loads the current file:

lua
iron.setup{
  config = {
    repl_definition = {
      haskell = {
        command = function(meta)
          local filename = vim.api.nvim_buf_get_name(meta.current_bufnr)
          return { 'cabal', 'v2-repl', filename}
        end
      }
    },
  },
}

The `meta` argument provides context about the current state when the REPL opens, including `current_bufnr` for the buffer number. The function returns the command table that Neovim will use to launch the REPL process.

This pattern covers cases where the correct REPL invocation depends on the current file, the project structure, or runtime state that is not known at configuration time.

REPL window placement: splits and floating windows

iron.nvim supports both split windows and floating windows for displaying the REPL. The `repl_open_cmd` configuration key controls which is used. For splits, you can use a raw Neovim command string:

lua
repl_open_cmd = "vertical botright 80 split"

This opens an 80-column vertical split at the bottom right. iron.nvim also provides helper functions in the `view` module that let you express window size dynamically rather than as a fixed number of columns or rows. Floats use `view.top`, `view.center`, and related functions:

lua
repl_open_cmd = view.top("10%")

The `view.center` function accepts one or two arguments. When given one argument, it uses that value for both dimensions. Size values can be either fixed numbers or percentage strings. The README notes that the function takes an argument for whether the orientation is vertical (true) or horizontal (false), allowing dimension calculations to differ by axis.

This level of configurability lets users place the REPL window wherever it is least intrusive given their screen size and workflow: a floating window at the top for quick checks, or a persistent split alongside the code for extended interactive sessions.

The library layer and how it extends iron.nvim

Beyond the user-facing plugin features, iron.nvim is designed to be a library that other Neovim plugins can depend on. The README identifies this dual identity explicitly: it is both a plugin and a library, allowing for better user experience and extensibility at the same time.

What this means in practice is that iron.nvim manages REPL process lifecycle, buffer attachment, and window management in a reusable Lua module rather than in monolithic plugin-internal code. A plugin that wants to send code to a REPL can import the iron.nvim API instead of reimplementing REPL process management.

The lua/ directory in the repository contains the module structure. The tests/ directory holds tests that are run with Neovim's headless mode via the Makefile:

lua
NVIM_APPNAME=nvim-iron-test
nvim --headless -u NONE -l tests/init.lua

Running tests with `NVIM_APPNAME=nvim-iron-test` isolates the test environment from the user's regular Neovim configuration, so the test suite does not depend on anything in the user's init files.

Installation, maintenance record, and comparison with vim-slime

The README shows installation via vim.pack.add, Neovim's built-in package manager:

lua
vim.pack.add({
  {
    src = "https://github.com/Vigemus/iron.nvim",
  }
})

This works with Neovim's native package management. The README notes that any plugin manager of your choice can be used in place of vim.pack.

vim-slime is the canonical alternative for sending text from Vim or Neovim to an external terminal multiplexer such as tmux or screen. The architectural difference is meaningful: vim-slime sends text to a running tmux pane, which can hold any process the user started externally. iron.nvim manages its own REPL process and window inside Neovim, without requiring tmux or another terminal multiplexer. Users who prefer the REPL visible as a Neovim window alongside their code buffer will find iron.nvim a more integrated fit; users who already have tmux-based workflows and want to send code to an existing external session will find vim-slime more appropriate.

iron.nvim also provides the library API for other plugins to build on, which vim-slime does not expose. The last push was on 2026-09-15 and there are no GitHub releases. The doc/ directory contains Neovim help documentation for the plugin, accessible via :help iron from inside Neovim once the plugin is installed.

Editorial conclusion

iron.nvim is the right tool for Neovim users who work interactively with interpreted languages, particularly Python, R, Haskell, or any language with a REPL, and want to send code from their editor buffer directly to the interpreter without switching terminals. The scratch_repl option and customizable window placement make it adaptable to different workflow preferences. It is not the right tool for teams that need a language server protocol client or debugging integration; iron.nvim is strictly about interactive execution, not code intelligence or breakpoint-based debugging. The last push was on 2026-09-15, and there are no GitHub releases. The plugin requires Neovim's Lua API and does not support Vim.

Frequently asked questions

How do I configure iron.nvim for a specific language?

Add a key for the language under repl_definition in the iron.setup config table. The key is the filetype name (for example, python, haskell, sh) and the value is a table with a command field that lists the REPL executable and arguments. The command can also be a Lua function that returns the command table dynamically at REPL open time.

Does iron.nvim support IPython as a Python REPL?

Yes. The README shows { "ipython", "--no-autoindent" } as an alternative command value for the Python REPL definition. The --no-autoindent flag is included to avoid indentation interference when pasting code.

Can iron.nvim open the REPL in a floating window?

Yes. Set repl_open_cmd to a view function such as view.top("10%") or view.center("30%", 20). The view module provides helper functions for positioning floats by percentage of the editor size or by fixed dimensions.

Official sources

  1. Official README
  2. Project repository