Open-source project
nushell/reedline avatar
nushell/reedline

Reedline: a modern line editor for Rust command line tools

A feature-rich line editor - powering Nushell

825 stars257 forksRustMIT

At a glance

What is it?
The readline-style crate behind Nushell's interactive prompt, with syntax highlighting, completions, multiline and Unicode support, and with Emacs, Vi and Helix edit modes you can plug into a Rust CLI.
Who is it for?
Reedline suits a Rust developer building an interactive CLI who wants history, completion and highlighting without pulling in a shell, and it suits Nushell contributors working on the prompt itself. It does not suit a project that needs a full terminal multiplexer or a shell, since it is only the line editor, not the shell around it.
Can I use it commercially?
Yes. MIT 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 5 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

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

Editorial analysis

The line editor that Nushell runs on

Reedline is a line editor crate in the tradition of bash's readline or zsh's zle, and the README's pitch is that it supports many of the modern conveniences of command line interfaces, including syntax highlighting, completions, multiline support and Unicode support. It is primarily developed as the interactive editor for Nushell, starting from version 0.60 of that shell, with the goal of providing a pleasant interactive experience. That relationship explains the shape of the crate. It is not a shell and not a terminal emulator, it is the piece that reads a line, renders it, handles keys and gives you history. The manifest describes it as a readline-like crate for CLI text input, with the Nushell Project Developers as authors, an edition of 2021 and a minimum Rust version of 1.95.0.

The basic loop is read_line and a signal

The smallest possible integration is short, and it shows the shape of the API. You create a Reedline, pass it a prompt, and loop on the result of read_line:

rust
use reedline::{DefaultPrompt, Reedline, Signal};

let mut line_editor = Reedline::create();
let prompt = DefaultPrompt::default();

loop {
    let sig = line_editor.read_line(&prompt);

The return value is a Signal, so the caller has to distinguish a successful line from a Ctrl-D or Ctrl-C, which the README's example treats as an abort, and any other signal is printed for inspection. Everything else in the crate is an extension of this object, since Reedline is built with a builder pattern where each capability is added with a with_ method: with_history, with_highlighter, with_completer, with_menu, with_hinter, with_validator and with_edit_mode. The prompt itself is a trait implementation rather than a string, and the examples directory shows transient and semantic prompts alongside the default one.

Edit modes: Emacs, Vi and Helix

Key handling is pluggable, which is the part that makes the crate usable by projects with different expectations. The default keymap comes from default_emacs_keybindings, and adding one is a call to add_binding with the modifier, the key and a ReedlineEvent:

rust
use reedline::{
    default_vi_insert_keybindings, default_vi_normal_keybindings, default_vi_visual_keybindings,
    EditMode, Reedline, Vi,
};

let mut line_editor = Reedline::create().with_edit_mode(Box::new(Vi::new(
    default_vi_insert_keybindings(),
    default_vi_normal_keybindings(),
    default_vi_visual_keybindings(),
)));

Vi mode is built from three separate keymap sets, insert, normal and visual. A third mode, Helix, arrived more recently and is described as selection-first editing, where motions carry the selection and verbs act on it, and the README points at an example you can run with cargo run --example helix. A KEYBINDINGS.md file in the repository root documents the defaults, and an example called list_bindings prints them at runtime, which is the fastest way to see what a given build actually does.

Highlighting, completion, hints and validation are separate traits

Each of the editor's smart features is a trait you implement or a default you enable. The Highlighter is responsible for colouring the line as you type, and the README shows an ExampleHighlighter built from a list of commands. The Completer produces candidates, and the example wires a DefaultCompleter with a minimum word length of 2 into a ColumnarMenu so the candidates appear in an interactive menu, with a Tab binding that opens the menu and moves to the next entry. The Hinter is the fish-style autosuggestion, a DefaultHinter with an italic light grey style in the example. The Validator handles line completion, and the DefaultValidator is the simple case where the line is accepted as it stands. History is another slot, and FileBackedHistory::with_file takes a size limit and a path:

rust
use reedline::{FileBackedHistory, Reedline};

let history = Box::new(
  FileBackedHistory::with_file(5, "history.txt".into())
    .expect("Error configuring history with file"),
);

Cargo features decide what you pull in

The feature list in the manifest is worth reading before you depend on the crate, because the defaults are empty. There is a bashisms feature, an external_printer feature for the example that prints through an external program, two SQLite features, sqlite and sqlite-dynlib, the first bundling rusqlite and the second using a dynamically linked library, a system_clipboard feature that enables arboard with Wayland data control support, and a libc feature that turns on crossterm's libc support. The examples that need them are gated accordingly, so the cwd_aware_hinter example requires the sqlite feature and paste_interceptor requires system_clipboard. On Android there is a specific dependency, fd-lock, because File::lock in the standard library is unsupported there before Rust 1.98. Unicode handling is not optional: unicode-segmentation and unicode-width are unconditional dependencies, which is the practical difference from a byte oriented line editor.

Fast moving, well documented, MIT

The project is actively changing. The crate version is 0.52.1, published on 2026-10-04 after 0.52.0 at the end of September and 0.51.0 in August, and the repository is not archived with the last push on 2026-10-18. That cadence means the API is still moving, so a project that depends on reedline should pin a version and read the changelog. Documentation is good, with the full API on docs.rs, a KEYBINDINGS.md for the defaults, a CONTRIBUTING.md and a UX_TESTING.md for working on the interaction design. The licence is MIT. The alternatives the README itself names are the shell built-in editors reedline is imitating, and the reason a Rust project wants its own is that readline and zle are C libraries tied to the shells that use them, while a Rust crate can expose the same behaviour with the highlighting, completion and menu machinery of a modern terminal interface.

Editorial conclusion

Reedline suits a Rust developer building an interactive CLI who wants history, completion and highlighting without pulling in a shell, and it suits Nushell contributors working on the prompt itself. It does not suit a project that needs a full terminal multiplexer or a shell, since it is only the line editor, not the shell around it. Before adopting, check the optional dependencies, since the clipboard, SQLite and external printer support are behind cargo features that are off by default, and pin a version since the crate moves fast between minor releases.

Frequently asked questions

What is reedline?

It is a Rust crate for building a command line line editor, in the tradition of bash's readline or zsh's zle, with syntax highlighting, completions, multiline and Unicode support. The full API is documented on docs.rs.

Which shell uses reedline as its interactive editor?

Nushell. The README says reedline is primarily developed as the interactive editor for Nushell, starting with version 0.60 of that shell.

How do I add a custom keybinding in reedline?

Start from default_emacs_keybindings(), call add_binding with a key modifier, a key code and a ReedlineEvent, then pass the keybindings to the edit mode with with_edit_mode. The README's example binds Alt+M to the BackspaceWord edit command.

Which edit modes does reedline provide?

Emacs, Vi with separate insert, normal and visual keymaps, and Helix, which is described as selection-first editing where motions carry the selection and verbs act on it.

What cargo features does reedline offer?

The list includes bashisms, external_printer, sqlite and sqlite_dynlib for the SQLite backed examples, system_clipboard for arboard based clipboard access and libc for crossterm's libc support. The default feature set is empty.

Official sources

  1. License: MIT
  2. nushell/reedline on GitHub
  3. Project website
  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/nushell-reedline.svg)](https://hysenlabs.com/projects/nushell-reedline)

Was this useful?