CLI tool
antirez/linenoise avatar
antirez/linenoise

linenoise: a two file C replacement for readline and libedit

A small self-contained alternative to readline and libedit

4,371 stars742 forksCBSD-2-Clause

At a glance

What is it?
A roughly 1600 line C library that gives a command line program line editing, history, completion and hints without a 30k line dependency. Good fit for small utilities that have no configure script; not a fit for anything expecting GNU readline key bindings.
Who is it for?
Adopt linenoise when you are embedding a prompt into a small C or C++ utility with no build system to spend on a dependency, and leave it alone when your users expect readline behaviour such as vi-style key bindings or a configuration grammar.
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?
Activity is slowing. The repository last received commits 6 months 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 November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • antirez/linenoise4,371 ★ · +16
Star history
Repository2026-09-232026-11-14
antirez/linenoise4.4k4.4k

16 Stars in the last 52 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why a program without line editing is a real defect

Most command line tools ask the user to retype the same command after a syntax error, when history would have saved the keystrokes. The usual fix is readline, which the README measures at 30k lines of code, with libedit at 20k. Linking a two hundred line utility against either is a heavy answer to a small problem.

The README names the two failure modes it grew out of. Large programs ship configure scripts that disable line editing when readline is missing, and Tclsh is given as the real world example. Smaller programs with no configure script skip line editing altogether, and redis-cli is the case the author had in front of him. A binary with no arrow key support is the result.

The audience is narrow and specific: authors writing a utility in C who want the up arrow to work out of the box, and maintainers of larger programs who want a fallback branch when their configure probe for readline comes back empty. It is BSD-licensed code, so it can be linked into commercial software as well as free software.

linenoise.c and linenoise.h are the whole library

The repository holds eight entries: linenoise.c, its header linenoise.h, an example, a test driver, a Makefile, a LICENSE, a README and a .gitignore. There is no configure script, no build system beyond that Makefile, and no external dependency. Dropping linenoise.c and linenoise.h into an existing project is the entire installation step for most users.

The blocking entry point takes a prompt and returns what the user typed:

c
char *linenoise(const char *prompt);

The returned string belongs to the caller and should be released with free(), or with linenoiseFree() when the host program links a different allocator. A NULL return means end of file or an out of memory condition, which is why the canonical loop tests the pointer rather than an error code.

Rendering stays inside a small VT100 subset, and no VT220 specific sequences are used, which is what lets the same code drive an ANSI.SYS terminal. The tested list runs from a Linux text console with $TERM set to linux through xterm, iTerm, Terminal.app, AIX 6.1 and Emacs comint mode with $TERM set to dumb. History, completion, hints shown to the right of the prompt, and a multiplexed mode that hides and restores the prompt for asynchronous output all sit behind this one API.

History stays disabled until linenoiseHistorySetMaxLen is called

Four calls cover persistence:

c
int linenoiseHistoryAdd(const char *line);
int linenoiseHistorySetMaxLen(int len);
int linenoiseHistorySave(const char *filename);
int linenoiseHistoryLoad(const char *filename);

The catch is in the defaults. History length is zero at startup, so the up arrow does nothing until linenoiseHistorySetMaxLen is called with a real number. A program that calls linenoiseHistoryAdd without setting that length ships a working binary with a dead feature.

Each linenoiseHistoryAdd pushes a line to the top of the list, which is the entry the up arrow reaches first. linenoiseHistorySave and linenoiseHistoryLoad write and read the whole history to a file the program chooses.

Single row by default, multiple rows behind linenoiseSetMultiLine

Default behaviour is single line editing: one row on screen, and text scrolls left as the user types past the right edge. That suits a program where answers are short. Where a user may paste a query or a paragraph, the README points at linenoiseSetMultiLine(1), which spreads the input over several screen rows and turns the same program into something closer to what readline gives. Passing 0 turns it back off.

Two more display behaviours matter for interactive programs. Hints render a suggestion to the right of the prompt as the user types, and the multiplexing mode hides the prompt, lets the program print asynchronous output elsewhere on the terminal, then restores the prompt and redraws the line.

Building example.c and linenoise-test.c with the shipped Makefile

There is no install step, no package, and no configure script. The repository is fetched and built with its own Makefile, which compiles the example and the test driver:

bash
all: linenoise-example linenoise-test

linenoise-example: linenoise.h linenoise.c example.c
	$(CC) -Wall -W -Os -g -o linenoise-example linenoise.c example.c

Run make in the source tree and two binaries appear. The README's canonical loop prints each line you type after a hello> prompt and frees it, which is the smallest possible way to confirm that escape sequences render on your terminal:

c
while((line = linenoise("hello> ")) != NULL) {
    printf("You wrote: %s\n", line);
    linenoiseFree(line); /* Or just free(line) if you use libc malloc. */
}

The make test target runs linenoise-test, which the repository ships as linenoise-test.c. No other runtime, and no library to install on the system.

LINENOISE_MAX_LINE caps what you can paste at a terminal

Two limits behave in opposite directions depending on stdin. When stdin is a tty, the maximum editable line is LINENOISE_MAX_LINE, and large pastes are accepted only up to that same bound. When stdin is not a tty, which is every redirection and every Unix pipeline, there is no limit at all on the length of the returned line.

That split is deliberate and useful, but it means a program behaves differently in a shell than under a supervisor. A paste that works in a test harness fails under an interactive terminal, and the failure is a length limit rather than a parse error.

A second detail is easy to miss. When the terminal advertises bracketed paste, a long or multi line paste is shown folded on screen, but the string returned by linenoise() is the real text the user pasted. Screenshots of the editor state will not match what your program receives. Development on the repository is also thin: it is not archived, but the last push was on 2026-05-02.

Where Replxx and readline differ in approach

Linenoise stays C and stays around 1600 lines, excluding comments and empty lines.

Against readline itself the difference is footprint and terms, not quality. readline brings GNU key bindings, a configuration grammar and a large binary; linenoise brings a prompt, arrow keys, history and completion, and nothing else. If a user of your tool has muscle memory for readline shortcuts beyond editing a line, the gap shows.

Editorial conclusion

Adopt linenoise when you are embedding a prompt into a small C or C++ utility with no build system to spend on a dependency, and leave it alone when your users expect readline behaviour such as vi-style key bindings or a configuration grammar. Before committing, compile example.c with the shipped Makefile, then paste a paragraph into the resulting binary to see whether the folded on screen form and the LINENOISE_MAX_LINE bound fit the way your program is actually used in practice, then decide whether the two source files are worth the maintenance you take on.

Frequently asked questions

What is a linenoise alternative?

The alternatives the README names are readline, at 30k lines of code, and libedit, its BSD clone, at 20k. Linenoise stays in C at about 1600 lines.

How do I build linenoise from the repository?

Run make in the source tree; the Makefile compiles linenoise-example and linenoise-test with $(CC) -Wall -W -Os -g. make test runs the linenoise-test binary, and make clean removes both binaries.

Does linenoise support history by default?

Not until you call linenoiseHistorySetMaxLen with a non zero length, since the default history length is zero and history stays disabled. Push entries with linenoiseHistoryAdd and persist them with linenoiseHistorySave and linenoiseHistoryLoad.

Official sources

  1. antirez/linenoise on GitHub
  2. Issues
  3. License: BSD-2-Clause
  4. README
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/antirez-linenoise.svg)](https://hysenlabs.com/projects/antirez-linenoise)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/antirez-linenoise.svg)](https://hysenlabs.com/projects/antirez-linenoise)

Was this useful?