Open-source project
emacs-ng/emacs-ng avatar
emacs-ng/emacs-ng

emacs-ng's headline Deno feature is disabled, and its releases stopped in February 2025

A new approach to Emacs - Including TypeScript, Threading, Async I/O, and WebRender.

1,809 stars75 forksEmacs LispGPL-3.0

At a glance

What is it?
emacs-ng adds Rust, WebRender and a Deno-based JavaScript runtime to Emacs, which is an ambitious brief. Two of its three headline features carry explicit unmaintained or disabled notices in the README, and the newest release tag predates the last push by eight months.
Who is it for?
Adopt emacs-ng only if you are specifically after the WebRender GPU backend or want to experiment with Rust inside Emacs, and if you are willing to track the master branch yourself, since the README pins its base to a merged commit from 2025-01-26 and the latest release tag is v0.0.d90af7b from 2025-02-09.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Emacs Lisp, according to GitHub's language statistics.

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

Editorial analysis

The base is a pinned upstream commit, not a version

emacs-ng is a fork of Emacs `master`, and the way it stays current is unusual enough to check first. The README says it regularly merges using GitHub Actions, with the run at 00:00 on Saturdays only. Then it names the specific commit: the last merged commit is `35d3927859`, dated 01 26 2025.

So the fork is not tracking head continuously. It takes a weekly merge and freezes at a known commit. That is a defensible choice for a fork, and it also means the feature list describes a snapshot rather than a moving target.

The repository is unmistakably an Emacs fork rather than an add-on. The top-level entries include `lisp/`, `lib/`, `lib-src/`, `leim/`, `m4/`, `lisp/`, `doc/`, `modules/`, `nt/`, `oldXMenu/` and `msdos/`, alongside the autoconf machinery `configure.ac`, `Makefile.in`, `GNUmakefile`, `autogen.sh` and `INSTALL.REPO`, plus the standard GNU files `COPYING`, `CONTRIBUTE`, `BUGS` and four `ChangeLog` files. The Rust side is layered on top: `Cargo.toml`, `Cargo.lock`, `crates/`, `cross/` and a `build = "./crates/codegen/etc/build.rs"` build script.

Primary language is recorded as Emacs Lisp and licence is GPL-3.0, which for a fork of Emacs is not a detail but a constraint on what can be taken back upstream.

The npm-like packaging story is also there: `flake.nix`, `flake.lock`, `default.nix` and a `nix/` directory, so Nix users can build it declaratively.

Two of the three headline features carry warning notices

This is the section to read before the marketing copy. Each feature in the README has a status label, and two of them are negative.

Dynamic modules come with a Warning: "This feature is currently unmaintained." The described capability is that dynamic modules can access more of Emacs's internals, while remaining fully compatible with vanilla Emacs.

Deno/Javascript comes with a longer note: "This feature is currently outdated and been disabled. However there is this to bring it back", linking to pull request 463.

So of the features listed, only WebRender is presented as live. The project description at the top of the repository, which advertises TypeScript, threading, async I/O and WebRender, does not carry those caveats, and neither does the topic list, which still includes deno, javascript, wasm and webassembly.

What remains is not nothing, because the Rust and WebRender plumbing is real and the Cargo manifest still wires up a `javascript` feature that pulls in the `js` crate:

toml
# Use JavaScript and Deno
javascript = ["dep:js"]

That is a build-time switch that compiles the JavaScript runtime in. Having the code present and the feature disabled is a different situation from having deleted it, and it is what makes pull request 463 a restoration rather than a rewrite. But if you build with default features, you do not get Deno.

The Rust surface is broader than the two headline items. `Cargo.toml` lists `emacs-sys`, `lisp-async`, `lsp-json` and an optional `ng-module`, plus `libc` and `tracing`. `lisp-async` is the threading piece, and `lsp-json` points at Language Server Protocol support, which the README's feature list does not mention at all.

The Cargo features map directly onto what gets built

Reading `Cargo.toml` is the most reliable way to know what an emacs-ng build actually contains, because the feature list is conditional rather than exhaustive.

The declared features are `use-xml2` to compile with C xml2 library support, `window-system-pgtk` for the GTK window system, `wr_pgtk` which pulls in `window-system-pgtk` plus `pgtk/webrender`, and `window-system-winit` for the alternative window system. There are also `libgit` to build with git2rs support, `strict` to treat warnings as build errors, `javascript` and `ng-module`.

The `js`, `git`, `ng-module`, `winit`, `pgtk` and `clippy` dependencies are all marked `optional = true`. Nothing Rust-related is unconditional except the core crates, so a build that skips every feature gets an Emacs that behaves like stock Emacs plus a static library nobody calls.

The output type is worth noting: `crate-type = ["staticlib"]` with `path = "./src/emacs.rs"`. The Rust side links into the C program as a static archive rather than exposing a dynamic module, which is consistent with the README's claim that dynamic modules stay compatible with vanilla Emacs but the core features are a fork.

There is a warning about feature selection in a comment in the manifest, and it is unusually candid. It says to avoid using optional-dependency syntax like `winit?/capture` because the codegen from lisp-util is not smart enough yet to work out when winit or pgtk should be enabled or not. In other words, the C and Lisp sides do not yet fully understand the Rust feature graph, and you configure it by editing the feature list rather than by describing dependencies.

WebRender is the feature that still works

WebRender is the one item described without a caveat. The README links it to the Servo repository and describes it as a GPU-based 2D rendering engine written in Rust from Mozilla, used by Firefox, the Servo browser and other GUI frameworks. emacs-ng uses it as an experimental graphic backend to leverage GPU hardware.

The word to hold onto there is experimental. This is not a default build path; the Cargo feature is `wr_pgtk`, which composes `window-system-pgtk` with `pgtk/webrender`. So enabling WebRender means building against the GTK window system specifically, not winit. On a machine where GTK is not what you use, that is a constraint rather than a detail.

The motivation section explains the intent without overselling it. The project says it is about exploring new development approaches, that it is not about replacing elisp with a more popular language like JavaScript, and that the goal is to make Emacs more approachable for people who do not like Lisp as much as its maintainers do. The README also describes the project as an additive native layer over Emacs rather than a replacement.

There is an FAQ page and a handbook on the project site, and contributing guidance asks you to open an issue before starting work so the team can give feedback, with issues tagged `good first issue` maintained as an onboarding list.

Building it, and a docker-compose file from an earlier name

The build path is Emacs's own plus Cargo, since the fork keeps the autoconf and gnulib infrastructure intact: `autogen.sh`, `configure.ac`, `Makefile.in` and a `gnulib.mk.in`. If you have built Emacs from source before, this part is familiar.

There is also a containerised path, and the file has a small piece of history in it. The `docker-compose.yml` at the repository root defines a single service named `remacs`, built from `docker/ubuntu/Dockerfile`, with the working directory set to `${PWD}`, `tty: true` and the current directory bind-mounted. The image is tagged `remacs-build:latest`.

The service and image names in this file do not match the project name. That is cosmetic on its own, but it does mean the service and image names in this file do not match the project name, which will confuse anyone searching the repository for build instructions.

The compose file also sets `privileged: true` with a comment explaining that dumping does not work without it. So the container runs privileged, which is fine for a local interactive build shell and not something to copy into a CI template.

Other build-related entries at the root include a `Dockerfile`-less `docker/` directory, a `docker-compose.yml`, `.envrc` for direnv, `.clang-format` and `.clangd` for the C side, and `mkdocs.yml` with a `generate-docs.sh` and a `docs/` directory for the project website.

What the release history says about where this is

The version scheme is the clearest signal. The recent releases are `v0.0.d90af7b` (emacs-ng_0.0.d90af7b) from 2025-02-09, `v0.0.2c26999` from 2025-02-02 and `v0.0.58fcf8c` from 2024-07-14. Each is a zero-major version whose suffix is a short git hash, which is how a project tags a fork build that tracks upstream rather than cutting its own releases.

The date pattern matters more than the scheme. The last push to the repository was on 2026-10-13 and it is not archived, so commits are still landing. But the newest release tag is from 2025-02-09, and the last upstream merge named in the README is 2025-01-26. Those two dates together tell you what someone installing a release gets: an Emacs from early 2025 with the Rust layer as it stood then.

So there are three distinct dates to keep apart. The repository is being committed to. The last release predates that by roughly eight months. And the upstream Emacs snapshot predates the release by days.

That is not a reason to avoid the project. It is a reason to treat emacs-ng as something you build from `master` rather than something you install, and to check whether the specific feature you want, WebRender or the Rust crates, has moved since early 2025. The README itself hints at this by pointing to an open pull request as the path to restoring the JavaScript feature.

Editorial conclusion

Adopt emacs-ng only if you are specifically after the WebRender GPU backend or want to experiment with Rust inside Emacs, and if you are willing to track the master branch yourself, since the README pins its base to a merged commit from 2025-01-26 and the latest release tag is v0.0.d90af7b from 2025-02-09. Do not adopt it expecting the documented JavaScript and TypeScript story: the README states that feature is currently outdated and disabled, with restoration work tracked in a pull request. Before you build, read the feature list in the README rather than the project description, and check whether your Deno or WebRender interest is better served by stock Emacs packages.

Frequently asked questions

What is the current status of the Deno and JavaScript support in emacs-ng?

The README marks it with a note saying the feature is currently outdated and has been disabled, linking to pull request 463 as the work to bring it back. The Rust `javascript` feature and the `js` crate are still present in Cargo.toml, so the code is compiled in when the feature is enabled rather than having been removed.

How does emacs-ng stay in sync with upstream Emacs?

The README says it is based off the `master` branch of Emacs and regularly merges using GitHub Actions, running at 00:00 on Saturdays only. It names the last merged commit as 35d3927859, dated 01 26 2025, so the fork tracks a weekly snapshot rather than head continuously.

Which Cargo features control WebRender and the window system?

`wr_pgtk` enables WebRender and composes `window-system-pgtk` with `pgtk/webrender`, while `window-system-winit` selects the alternative window system. Other declared features include `use-xml2`, `libgit`, `strict`, `javascript` and `ng-module`. A comment in Cargo.toml warns against optional-dependency syntax because the codegen from lisp-util cannot infer when winit or pgtk should be enabled.

How do I build emacs-ng in a container?

The root docker-compose.yml defines one service built from docker/ubuntu/Dockerfile with the working directory set to ${PWD}, tty enabled and the current directory mounted. It sets privileged: true because dumping does not work without it.

Official sources

  1. emacs-ng/emacs-ng on GitHub
  2. License: GPL-3.0
  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/emacs-ng-emacs-ng.svg)](https://hysenlabs.com/projects/emacs-ng-emacs-ng)

Was this useful?