# emacs-libvterm: a C-backed terminal emulator inside Emacs, and its alpha-stage trade-offs

> emacs-libvterm (vterm) brings a full terminal into GNU Emacs by wrapping libvterm, a C library from the Neovim project. It handles ncdu, htop and other interactive tools that the 3 built-in Emacs terminals cannot, but the alpha-stage warning in the README means the public interface changes and bugs can produce segmentation faults.

**akermu/emacs-libvterm** — Emacs libvterm integration

- Repository: https://github.com/akermu/emacs-libvterm
- Stars: 1,998 · Forks: 175
- Language: Emacs Lisp
- License: GPL-3.0
- Published: 2026-10-09 · Updated: 2026-10-09 · Language: en
- Canonical page: https://hysenlabs.com/projects/akermu-emacs-libvterm

## eshell, shell, and term each have a specific gap that vterm's C core addresses

GNU Emacs ships with 3 terminal-like environments, and each has a concrete limitation. eshell implements a full shell in Elisp and works on Windows, but programs that need direct terminal manipulation, such as ncdu and nmtui, fail because eshell never provides a real terminal surface.

shell pipes input to a real shell like bash and returns its output as Emacs text. Interactive programs like htop require control over the display itself, which that pipe model cannot provide.

term and ansi-term go further: they actually run a shell the way Gnome Terminal does, handing escape codes through to programs. The problem is that the escape code implementation is incomplete, so some programs still break, and the Elisp processing path creates performance problems with large output bursts.

vterm replaces the Elisp terminal emulation layer with libvterm, a C library. That library handles escape codes comprehensively because it was written for Neovim, where terminal compatibility and speed are first-class concerns. The README places vterm's compatibility at nearly universal and uses the Gnome Terminal comparison to set expectations: fast and capable, but less tightly woven into Emacs than eshell.

## libvterm is an external C library, and the module it produces compiles at first run

The architecture differs from the other Emacs terminal implementations. Instead of implementing terminal emulation in Elisp, emacs-libvterm compiles libvterm as a dynamic Emacs module and loads it at runtime. The repository root shows the evidence: vterm-module.c, vterm-module.h, elisp.c, elisp.h, utf8.c, utf8.h, and a CMakeLists.txt, all at the top level. Those are the C source files and the build configuration that produce the loadable module.

libvterm packages exist in the official repositories for Arch, Debian, Fedora, Gentoo, openSUSE and Ubuntu, with the package named libvterm on most distributions and libvterm-dev on Debian and Ubuntu. When the system copy is absent, the build fetches the latest libvterm source from the Neovim mirror and compiles it locally. Passing -DUSE_SYSTEM_LIBVTERM=no to cmake skips the system lookup and uses that vendored copy unconditionally, which avoids surprises when the installed version is old.

This architecture is the reason for both the performance advantage and the risk: compiled C code handles terminal emulation faster than Elisp can, but bugs in that path can produce segmentation faults and crash the Emacs process. The README states this directly and asks users to file a report at the issue tracker when that happens. A crash in eshell or shell loses the terminal session; a segfault in vterm loses the whole Emacs instance, including unsaved buffers.

## MELPA is the recommended install path, and cmake >= 3.11 must be on the system first

4 prerequisites must be in place before vterm can compile its C module: GNU Emacs >= 25.1 with module support enabled, cmake >= 3.11, libtool-bin, and optionally libvterm >= 0.2 from the system package manager. Emacs does not ship with module support in all build configurations, so confirm it is available by checking that module-file-suffix evaluates to a non-nil value before attempting any install.

From MELPA, the minimal configuration is a single stanza in init.el:

```elisp
(use-package vterm
    :ensure t)
```

When Emacs loads vterm for the first time, it invokes cmake to build the C module from the package source. The build happens automatically if cmake and the required libraries are present; a missing dependency surfaces as a compile error at that point rather than at install time.

For a manual install, clone the repository and build the module with cmake:

```sh
git clone https://github.com/akermu/emacs-libvterm.git
cd emacs-libvterm
mkdir -p build
cd build
cmake ..
make
```

After the build completes, add the path to your init.el:

```elisp
(add-to-list 'load-path "path/to/emacs-libvterm")
(require 'vterm)
```

On Ubuntu < 20.04 and Debian < 11, the system libvterm packages predate the VTERM_COLOR API that emacs-libvterm requires. Those versions trigger compile errors, and the fix is to set the cmake flag -DUSE_SYSTEM_LIBVTERM=no so the build downloads and compiles the vendored libvterm instead.

## Ubuntu 20.04 ships without cmake and lacks Emacs27 in its default repository

The README devotes a section to Ubuntu 20.04 because the default package state on that LTS release blocks a standard vterm install. Ubuntu 20.04 ships without cmake installed and Emacs27 is not in the Ubuntu package repository at that version.

Emacs27 is not in the Ubuntu 20.04 default repositories, so it requires a separate installation step. Compiling from source, using Snap, and Kevin Kelley's PPA are the 3 paths the documentation names. For the PPA path, purge any older Emacs package first to avoid conflicts:

```sh
sudo apt --purge remove emacs
sudo apt autoremove
```

Then add the PPA and install Emacs27:

```sh
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt install emacs27
```

The README notes that on Ubuntu 20.04, cmake, libtool and libtool-bin also need to be installed separately since the release does not include them by default.

Ubuntu and Debian versions older than 20.04 and 11 respectively have a second problem: their system libvterm is too old and triggers VTERM_COLOR errors at compile time. For those distributions, the system libvterm should be bypassed by using the cmake -DUSE_SYSTEM_LIBVTERM=no flag. These are not hypothetical edge cases: the README addresses them explicitly because they were recurring enough to warrant documentation.

## Alpha stage means public interface changes happen and segfaults crash Emacs, not just the terminal

emacs-libvterm carries an alpha warning in the introduction: option names and function names may change between versions. A breaking-changes appendix in the project documentation tracks what has changed, and checking that list before an upgrade is the practical way to avoid configuration breakage.

Alpha does not mean the package is unstable for regular use. Many users run it as their primary terminal in Emacs. The instability shows up in edge cases and uncommon configurations, not in the core workflow of opening a terminal and running commands.

The risk worth understanding before adoption is what happens when a bug occurs. Because terminal emulation runs in compiled C, a bug at that layer can produce a segmentation fault and crash the entire Emacs process. A broken eshell session drops a terminal buffer; a segfault in vterm ends all open buffers and any unsaved work in the session. Users who rely on Emacs for long-running editing sessions should account for that difference.

Breaking changes in option names and function names matter most to users who configure vterm explicitly. A user who installs via MELPA and accepts the defaults will encounter these changes at upgrade time when a setting they set by name no longer exists under that name.

## Windows is unsupported, and evil-mode does not work because keys go directly to the shell

Windows is not supported. A GitHub issue tracks the gap, and the documentation names it directly as a reason to use one of the Elisp-based alternatives instead.

evil-mode presents a different constraint. vterm sends keystrokes directly to the shell process rather than routing them through the Emacs command dispatcher. That design is what lets interactive programs receive their own key sequences without interference, but it also means evil-mode bindings never fire inside a vterm buffer. Users who heavily rely on evil-mode outside the terminal will have to context-switch: modal editing outside, terminal's own bindings inside.

VI emulation in the shell is a workaround but a different thing. Enabling VI mode in bash or zsh gives vi-style line editing for command input. That is not evil-mode: it does not apply to buffer navigation or to any content outside the current command line.

More broadly, vterm trades Emacs integration for terminal compatibility. The Gnome Terminal comparison in the project documentation sets the expectation: what a standalone terminal does, vterm does inside Emacs, with the same gap in editor integration. eshell works the opposite way, behaving like an Emacs buffer at the cost of missing programs that need a real terminal.

## GPL-3.0 licence and last push on 2026-09-14; no GitHub releases and no changelog file listed

emacs-libvterm is distributed under the GPL-3.0 licence. That licence applies to any modifications made to the package and to projects that distribute vterm as part of a larger work. The LICENSE file at the repository root is the file to read before redistributing a modified build.

No GitHub releases exist in the repository. Version tracking happens through the commit history rather than a tagged release. For users who want to know when the interface last changed, the breaking changes appendix in the README is the primary record.

The last push to the repository was on 2026-09-14. The repository is not archived.

Since vterm is available on MELPA, version management in practice goes through Emacs's package system. Users who install via MELPA and update packages through Emacs will receive the latest MELPA version, not necessarily the latest commit. Pinning to a specific MELPA snapshot is the path for users who want predictable behavior across upgrades.

The CMakeLists.txt and the C source files at the top level mean that any change to the C module requires a recompile. After upgrading the Elisp package via MELPA, if the C module has changed, vterm will recompile the module on next use. Whether that is triggered automatically depends on the MELPA package version published at the time of upgrade.

## Conclusion

Use vterm if you live in Emacs and regularly need interactive programs like ncdu, htop, or tmux, and your machine is not Windows. The MELPA install is the recommended path; run (use-package vterm :ensure t) and let Emacs compile the module on first startup. Before you depend on it, verify that your Emacs was built with module support by checking that module-file-suffix is not nil, and check the breaking-changes appendix in the README if you are upgrading from an earlier configuration. On Ubuntu 20.04, confirm you have Emacs27 or newer before trying to compile the module, because the default repository package is older. Avoid vterm if you use evil-mode heavily, since keys go directly to the shell and evil-mode is not supported.

## FAQ

### What is emacs-libvterm?

emacs-libvterm (vterm) is a terminal emulator for GNU Emacs backed by libvterm, a C library originally written for Neovim. It supports interactive terminal programs like htop and ncdu that the built-in eshell and shell modes cannot handle.

### How do I install vterm in Emacs?

The MELPA package is the recommended path. Add (use-package vterm :ensure t) to your init.el, and vterm will compile its C module on first run. The system must have cmake >= 3.11 and libtool-bin installed, and Emacs must be built with module support.

### Does emacs-libvterm work on Windows?

No. The README states directly that vterm is not for Windows users and links to a GitHub issue tracking that gap. eshell remains the main option on Windows because it runs entirely in Emacs Lisp.

### Why does emacs-libvterm crash Emacs instead of just the terminal?

vterm uses a compiled C module based on libvterm to handle terminal emulation. A bug in that compiled code can produce a segmentation fault, which crashes the Emacs process. The README acknowledges this and asks users to report it at the issue tracker.

### Does evil-mode work inside vterm?

No. vterm sends keys directly to the shell, which means evil-mode bindings do not activate inside a vterm buffer. The README notes that users can enable VI emulation in their shells as a shell-level alternative, but that is separate from evil-mode.

## Sources

- [akermu/emacs-libvterm on GitHub](https://github.com/akermu/emacs-libvterm)
- [Issues](https://github.com/akermu/emacs-libvterm/issues)
- [License: GPL-3.0](https://github.com/akermu/emacs-libvterm/blob/master/LICENSE)
- [README](https://github.com/akermu/emacs-libvterm/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/akermu-emacs-libvterm
