antirez/linenoise: a 1600-line readline replacement for C programs
A small self-contained alternative to readline and libedit
At a glance
- What is it?
- Linenoise is a BSD-licensed line editing library that gives small C utilities history, completion and hints without pulling in readline or libedit. It is easy to embed, but it is not a drop-in readline clone.
- Who is it for?
- Adopt Linenoise when a C utility needs interactive line editing and you want BSD licensing plus a small source footprint; skip it when you need readline's full key binding set, vi mode or a stable public API, and verify the linenoise.h declarations and the example.c loop against your own terminal before committing to it.
- Can I use it commercially?
- Yes. BSD-2-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 151 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem linenoise solves for small C programs
Most command line utilities want the same handful of interactive features: a prompt, arrow-key history, and line editing so a typo does not force a full retype. The conventional way to get them is to link readline or libedit, which the README describes as 30k and 20k lines of code respectively. For a small binary that is a poor trade. The README lists the two outcomes it wants to avoid: larger programs add configure checks that disable line editing when readline is absent, or they skip it entirely because readline is GPL licensed and libedit is less widely available. Smaller programs with no configure script often ship with no line editing at all, which the author names as the situation redis-cli was in.
Linenoise is aimed at exactly that gap. It is BSD-2-Clause, self-contained, and the README puts it at about 1600 lines excluding comments and blank lines. It is for the maintainer of a C tool who wants history and completion in the binary without a dependency negotiation. It is not for an application that expects readline semantics down to the key binding level.
What the linenoise API actually gives you
The core call is a single blocking function that prints a prompt and returns the line the user composed, or NULL on end of file or out of memory. The returned buffer must be released with free, or with linenoiseFree when your program uses a different allocator than the one linenoise was built with. The README gives the canonical loop as a while over linenoise("hello> ") with a printf and a linenoiseFree inside.
History is opt-in. linenoiseHistorySetMaxLen must be called or history stays disabled, because the default length is zero. Once a length is set, linenoiseHistoryAdd pushes a line to the top, and linenoiseHistorySave plus linenoiseHistoryLoad persist the list to a file. Multi-line editing is a separate switch, linenoiseSetMultiLine(1), for programs where users type long input and a single scrolling row is uncomfortable. Completion and hints are part of the same surface: hints appear to the right of the prompt as you type. The README also documents a multiplexing mode with prompt hiding and restoring for asynchronous output, and bracketed paste support that folds large or multi-line pastes on screen while still returning the real pasted text.
Terminal assumptions and the VT100 subset
The design bet is that basic VT100 escape sequences are enough. The README states that no VT220 specific sequences are used, which is what makes ANSI.SYS compatibility possible. The tested list is a period piece: Linux text console with TERM=linux, xterm, KDE terminal, Buildroot with TERM=vt100, iTerm and Terminal.app on macOS, OpenBSD over an OSX terminal with TERM=screen, IBM AIX 6.1, FreeBSD xterm, ANSI.SYS, and Emacs comint mode with TERM=dumb. The author asks for reports from other environments, which is a fair signal that the list is a starting point rather than a guarantee.
The practical consequence is that linenoise does very little terminal detection and no terminfo lookup. That keeps the code small and the binary portable, and it also means exotic terminals or unusual key encodings are handled on a best-effort basis. If your users run something far from that list, the tested matrix is the thing to check before you commit.
Building linenoise and a first prompt
The repository has no configure script and no package manifest. The Makefile defines two targets: linenoise-example, built from linenoise.c and example.c, and linenoise-test, built from linenoise-test.c. Running make builds both, and make test runs ./linenoise-test. There is no install target in the Makefile, so adoption means copying linenoise.c and linenoise.h into your tree and compiling them with your sources.
make
./linenoise-exampleAfter that you should see the example prompt and be able to type a line, press the up arrow to recall it, and edit it before submitting. The README points at example.c as the reference for wiring the library into a program, and the loop it documents looks like this:
char *line;
while((line = linenoise("hello> ")) != NULL) {
printf("You wrote: %s\n", line);
linenoiseFree(line);
}To make history survive between runs, set a maximum length before adding entries, then save and load a file. The README names linenoiseHistorySetMaxLen, linenoiseHistoryAdd, linenoiseHistorySave and linenoiseHistoryLoad for this; without the length call history is disabled even if you add entries.
Where linenoise is the wrong tool
The README is explicit that this is a minimal replacement, not a full one. If your program depends on readline's complete key binding set, vi editing mode, or the readline configuration files users expect to customize, linenoise will not satisfy them, and the README does not claim otherwise. The same applies to applications that need a stable, versioned API: there are no releases, the default branch is master, and the README itself asks that patches respect the project's preference for small, easy to understand code. That preference is a constraint on how much surface area will ever be added.
Two smaller limits are worth noting. In tty mode the maximum editable line length is LINENOISE_MAX_LINE, and large pastes are accepted up to the same limit; only when standard input is not a tty, such as a redirected file or a pipeline, does the length limit disappear. And the README states the library returns NULL on end of file or out of memory, so callers must treat NULL as a normal exit path rather than an error.
How linenoise compares with readline and replxx
The difference against readline is scope and licence. Readline is the reference implementation with the largest feature set, and it is GPL licensed, which is why the README frames it as a problem for programs that cannot take that licence. Linenoise offers a subset of the editing experience under BSD-2-Clause, at roughly a twentieth of the line count, with no configure step. If your project already links readline and can accept its licence, there is no reason to switch.
Replxx is the other name that comes up in searches around this project. It targets the same need, an embeddable line editor with history and completion, but it is a C++ library with a different API and a larger feature surface. That makes it a reasonable choice when the host program is C++ and wants more than linenoise offers, and a poor fit for a C project that picked linenoise precisely to avoid a C++ dependency and a bigger build. The decision is mostly about language and footprint, not about which editor feels better.
Licence, maintenance and the cost of upgrading
Linenoise is BSD-2-Clause, and the README states plainly that this lets you use it in both free software and commercial software. That is the whole licence story; there is no separate contributor agreement or commercial tier mentioned. As with any dependency, the obligations that apply to your distribution are a matter for your own legal review, not something this article can settle.
The upgrade cost is low in one direction and awkward in another. Because there is no package to install and no versioned release, most adopters vendor linenoise.c and linenoise.h into their repository. Pulling in upstream changes then means diffing those two files against master and reapplying local edits, which is manageable at 1600 lines but does mean your copy can drift. The last push to the repository was on 2026-05-02, so the code is not abandoned, but the project's stated preference for small patches suggests the API will move slowly rather than grow. Budget for reading the diff, not for a migration guide.
Editorial conclusion
Adopt Linenoise when a C utility needs interactive line editing and you want BSD licensing plus a small source footprint; skip it when you need readline's full key binding set, vi mode or a stable public API, and verify the linenoise.h declarations and the example.c loop against your own terminal before committing to it.
Frequently asked questions
What is linenoise?
Linenoise is a small, self-contained line editing library written in C, described in its README as a readline replacement. It provides single and multi-line editing, history, completion, hints, bracketed paste and UTF-8 support in roughly 1600 lines of BSD-2-Clause source.
How do I build and try linenoise?
The repository ships a Makefile with linenoise-example and linenoise-test targets. Running make builds both, and make test runs ./linenoise-test; the README points to example.c as the reference for embedding the library.
Is linenoise a drop-in replacement for readline?
No. The README presents it as a minimal replacement, and readline offers a much larger feature set including the full key binding behaviour users expect. Linenoise covers the common editing and history cases under a BSD licence instead of readline's GPL.
How does linenoise handle history?
History is disabled until you call linenoiseHistorySetMaxLen, since the default length is zero. You add entries with linenoiseHistoryAdd and can persist them with linenoiseHistorySave and linenoiseHistoryLoad.
Does linenoise work on non-tty input?
Yes. The README states that when standard input is not a tty, as with a redirected file or a pipeline, there is no limit to the length of the line returned. In tty mode the editable line is capped at LINENOISE_MAX_LINE.
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/antirez-linenoise)