Lem: a Common Lisp editor you extend while it runs
General-purpose editor/IDE with high expansibility in Common Lisp
At a glance
- What is it?
- Lem is a general-purpose editor and IDE written in Common Lisp, with ncurses, SDL2 and webview frontends. Its extension model is the reason to look at it, and also the reason to be careful.
- Who is it for?
- Adopt Lem if you already write Common Lisp or want an editor whose extension language is the same language as the editor, and you accept nightly builds as the documented distribution channel. Skip it if you need a stable tagged release, a Windows-first workflow, or an Emacs-compatible configuration and keybinding set, since the README explicitly lists imitating Emacs or Vim as a non-goal.
- 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 1 day ago.
- What is it written in?
- Mainly Common Lisp, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Lem solves, and for whom
Lem is a general-purpose editor and IDE whose implementation language is Common Lisp. The README states the vision directly: "Lem brings the distance between code and its execution state as close to zero as possible," with users seeing results while editing and following running code in real time. That framing tells you who the project is aimed at. If you write Common Lisp, the editor and your program share a runtime model, so an extension is ordinary Lisp code rather than a plugin written against a foreign host API. The README says that after installing lem you can start developing and extend the editor while it runs, which is the same image-based workflow Lisp programmers already use for their own applications. The secondary audience is anyone who wants a small editor they can reshape without learning a bespoke extension language. The README's non-goals section is worth reading before anything else: rather than imitating Emacs or Vim, Lem pursues its own approach. If your muscle memory and your config file are the product of either of those editors, Lem is not promising compatibility, and you should read the rest of this as a question of whether the extension model is worth relearning keybindings for.
Frontends, the build targets, and how the pieces fit
Lem is not one program. The repository has a frontends/ directory, and the Makefile exposes separate targets for each user interface: ncurses for the terminal, sdl2 for a graphical window, webview for an embedded browser view, plus combined targets such as sdl2-ncurses and webview-ncurses. There is also a server and client pair, built by the server and client targets, which splits the editor core from the display. The default variant in the Makefile is webview, and the lem target simply depends on webview. Builds go through qlot, a Quicklisp-based dependency manager: most targets begin with qlot install and then load .qlot/setup.lisp before the relevant script under scripts/, such as scripts/build-ncurses.lisp or scripts/build-webview.lisp. The Makefile also defines minimal-build, which the comment says does not include any of the extensions and uses the ncurses frontend. That is the closest thing to a lean configuration the build system offers. One target, terminal-lib, builds a native helper called terminal.so from scripts/build-terminal.lisp and needs libvterm plus a C toolchain. The Makefile comment states that the editor targets invoke it best-effort via a leading hyphen, so a missing libvterm or compiler is non-fatal, and lem-terminal silently disables itself at runtime when the library is missing. That is a deliberate design decision: a feature that quietly turns itself off rather than failing your build.
Installing Lem with Nix, Docker or a nightly build
The README lists three install paths. The nightly build is described as tested on Ubuntu 24.04 and macOS on Apple silicon, and is published as a GitHub release. Nix users get four packages: lem, lem-ncurses, lem-webview and lem-sdl2. The README gives this command for adding the default package to a Nix profile.
Running Lem temporarily and from Docker
The nix run form fetches and starts Lem in one step, again with a fragment selecting the frontend.
The Docker image and what it builds
The published image is ghcr.io/lem-project/lem:latest, and the README labels it the terminal version.
NixOS and home-manager integration
For a flake-based NixOS or home-manager configuration, the README documents an overlay so that pkgs.lem-ncurses and apps.lem-ncurses come from your nixpkgs set. The example adds the overlay and installs the package.
Building from source with qlot
If you are not on Nix and do not want the container, the Makefile is the entry point. Every build target runs qlot install first, so qlot has to be present. The terminal build is:
Where Lem is the wrong tool
The distribution model is the first limitation. The recent releases are nightly builds, tagged nightly-latest, nightly-macos-latest and dated Linux builds. There is no stable versioned release in that list, so if your team needs a pinned artifact with a changelog you can diff between upgrades, the README does not document one. The README also does not document rollback, and it does not describe how an extension you wrote against one nightly survives the next. The second limitation is the extension model itself. Live editing of a running editor is powerful when it works and unforgiving when it does not: a broken definition can leave the editor in a state you cannot easily reason about, and the README does not describe an extension sandbox, a reload story, or a recovery procedure. The third is scope. The non-goals section rules out imitating Emacs or Vim, so anyone arriving with an existing Emacs configuration, Org files or Vim keybindings should expect to rebuild that workflow rather than port it. And the terminal helper is optional by design: the Makefile comment says lem-terminal silently disables itself when libvterm or a compiler is missing, which means a feature you expected can be absent with no error, only a runtime behaviour difference.
How Lem differs from Emacs
The obvious comparison is Emacs, and the README addresses it by refusing the comparison. Emacs is written in C with a Lisp interpreter embedded and a large body of Emacs Lisp packages; Lem is written in Common Lisp and its extensions are Common Lisp, loaded into the running image. The practical difference is what you can reach from an extension. In Lem, the editor core and your code are the same kind of object, so the boundary between editing the editor and editing your program is thinner than in a C-host-with-scripting-layer design. The cost is ecosystem. Emacs carries decades of packages written against its own APIs; Lem's extensions directory is the project's own, and the README's goals include offering an intuitive and consistent API for extensions, which reads as an admission that this is still being worked out. The other difference is packaging. Emacs ships stable releases; Lem's documented channel here is nightly plus Nix and Docker. If you want a Lisp-based editor with a stable release cadence and a package archive, Emacs remains the safer choice, and Lem is the choice when you specifically want the extension language to be the implementation language and you are willing to track nightlies.
Editorial conclusion
Adopt Lem if you already write Common Lisp or want an editor whose extension language is the same language as the editor, and you accept nightly builds as the documented distribution channel. Skip it if you need a stable tagged release, a Windows-first workflow, or an Emacs-compatible configuration and keybinding set, since the README explicitly lists imitating Emacs or Vim as a non-goal. Before committing, verify that the frontend you want builds on your machine (the Makefile targets are webview, ncurses, sdl2 and the combined variants), and check what the nightly-latest release contains for your platform.
Frequently asked questions
How do I install Lem on Linux?
The README lists a nightly build tested on Ubuntu 24.04, Nix packages such as lem-ncurses and lem-webview, and a Docker image at ghcr.io/lem-project/lem:latest for the terminal version. Building from source goes through the Makefile targets, for example make ncurses, which run qlot install first.
Is Lem the same as Emacs?
No. The README's non-goals state that rather than imitating Emacs or Vim, Lem pursues its own unique approach. Lem is written in Common Lisp and its extensions are Common Lisp loaded into the running editor, so an existing Emacs configuration does not carry over.
Which frontends does Lem support?
The Makefile exposes ncurses, sdl2, webview, minimal-build, server and client targets, plus combined variants such as sdl2-ncurses and webview-ncurses. The default VARIANT in the Makefile is webview.
Does Lem need libvterm?
Only for the lem-terminal native helper. The Makefile comment says terminal-lib requires libvterm and a C toolchain, and that the editor targets invoke it best-effort, so a missing library or compiler is non-fatal and lem-terminal silently disables itself at runtime.
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/lem-project-lem)