gudzpoz/Juicemacs

An absolutely-not-solid Emacs implementation (WIP)

Java

58

347 commits

updated Dec 22, 2025

See the code

README

#+title: Juicemacs - An absolutely-not-solid Emacs implementation

[[https://justforfunnoreally.dev][https://img.shields.io/badge/justforfunnoreally-dev-9ff.svg]]
[[https://openjdk.org/projects/jdk/25/][https://img.shields.io/badge/Java-25-orange.svg?logo=openjdk&ext=.svg]]
[[https://emacsen.de/dev/tests/][https://emacsen.de/dev/tests.svg]]
[[https://app.codecov.io/gh/gudzpoz/Juicemacs/][https://img.shields.io/codecov/c/github/gudzpoz/Juicemacs?label=coverage&ext=.svg]]
[[https://emacsen.de/dev/bench/][https://img.shields.io/badge/benchmark-charts-blue?ext=.svg]]
[[https://juice.zulipchat.com][https://img.shields.io/badge/chat-white?style=social&logo=zulip&ext=.svg]]

Juicemacs is a work-in-progress Emacs implementation +just for the fun of it+
that over-ambitiously aims to explore the following:

- Speculative JIT compilation
- Transparent(-ish) concurrentization of ELisp code
- Polyglot programming with Python, JavaScript, etc.
- GNU Emacs 30 compatibility

Java helps to make all these possible, for it runs on JVM, which happens to be a
platform with several nice things:

- A decent GC: HotSpot has a number of state-of-the-art GCs.
- Green threads & OS threads: One without the hassle of function coloring.
- An incredible JIT framework: [[https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/][Truffle]] lets you build an interpreter and a JIT
  compiler all at once.

Of course using Java brings in its own problems, which this project will need to
live with:

- Sloooow startup (and with Truffle, it actually needs two warm-ups)
- It bloats (and we can only hope Project Valhalla somehow tackles that)

* Running

Currently, Juicemacs has two functional interpreters (one for AST, one for
bytecode) and enough built-in routines implemented to handle =pdump=. It
usually stops when =top-level= tries to use unimplemented UI subroutines.

To run it:
1. Make sure to have JDK 25 installed (preferably [[https://github.com/graalvm/graalvm-ce-builds/releases/][graalvm-ce]]).
2. Clone the repository, go to [[file:elisp/emacs/]] and build a GNU Emacs to have
   all the generated data/elisp files ready.
3. Run =sh -c "cd app && $(./gradlew -q :app:jvmCmd)"= (in the project root) for
   a REPL.

#+begin_quote
If you're on Windows or just can't run the command above, it basically just does
the following:
1. Run the =:app:jvmCmd= Gradle task, which will produce a command with the
   correct JVM flags to make the JIT magic from Truffle work.
2. Run the produced command under the =app/= directory, because we currently
   hard-code the Emacs directory path to help with our tests. You can also use
   the =-L/--directory= option to specify a Lisp source directory.
#+end_quote

By the way, you may also try:
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --help"=
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --inspect=4242"= (for a [[https://www.graalvm.org/latest/tools/chrome-debugger/][Chrome
  DevTools protocol server]])

And specially, if you want to try out the experimental slowish pdump:
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --dump=pdump"=
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --dump-file ./emacs.pdmp"=

We also support [[https://www.graalvm.org/latest/reference-manual/native-image/][Java native images]]:

- =./gradlew :app:nativeCompile= (pdump is much faster with native images)

** ERT Testing

Emacs comes with a unit-testing toolkit, Emacs Lisp Regression Testing (ERT),
and has a bunch of ELisp tests in its source repository (=./test/src/=).
Juicemacs currently can run some of these tests [[file:elisp/src/test/java/party/iroiro/juicemacs/elisp/ELispRegressionTest.java][with a bit of workaround]]:

#+begin_src elisp
  ;; TODO: pp requires a bunch of sexp parsing functions
  (require 'pp)
  (defalias 'pp 'princ)
  ;; ert asserts about newlines produced by pp
  (defun cl--assertion-failed (&rest _) t)

  (require 'ert)
  (load "../test/src/data-tests")
  (ert-run-tests-batch)
  (null (ert-run-tests-batch)) ; don't print the huge info object
#+end_src

You're welcome to try the tests and report any failing cases! (I think many of
them might simply throw an =UnsupportedOperationException= since they are yet to
be implemented.)

* Contributing

Check out [[file:CONTRIBUTING.org]] for a walkthrough. Check out [[file:docs/TODO.org]]
or search for =UnsupportedOperationException= or =TODO= in code for
things that need more work.

* Documentation

- [[file:elisp/README.org]]: Documenting the structure of the ELisp interpreter
- [[file:commons/piece-tree/README.org]]: Introduction to a [[https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation][piece tree]]
- [[file:docs/Notes.org]]: Reading list and notes for implementing this Emacs clone
- [[file:docs/Bytecode.org]]: Extracting (part of) the Emacs bytecode specs from
  Emacs
- [[file:docs/NativeComp.org]]: Looking into Emacs =native-comp= and how we can
  reuse it for a more efficient bytecode interpreter
- [[file:docs/TODO.org]]: TODO list & DONE list, tracking current/solved challenges

** Blog posts

- [[https://kyo.iroiro.party/en/posts/emacs-lisp-interpreter-with-graalvm-truffle/][Writing a Lisp JIT Interpreter with GraalVM Truffle]]
- [[https://kyo.iroiro.party/en/posts/why-rewriting-emacs-is-hard/][Why Rewriting Emacs Is Hard]]

* Similar projects

- https://github.com/remacs/remacs

- https://github.com/CeleritasCelery/rune

- https://github.com/federicotdn/pimacs

- https://codeberg.org/ramin_hal9001/schemacs

- [[https://www.cliki.net/cl-emacs][CL-Emacs]]: “Various people have proposed an emacs-like editor written in Common
  Lisp. This page collects together a few possibilities.”

- Also the discontinued [[https://jemacs.sourceforge.net/][JEmacs - the Java/Scheme-based Emacs Text Editor]] (source
  @ [[https://gitlab.com/kashell/Kawa/-/tree/master/gnu/jemacs?ref_type=heads][GNU Kawa]])

* Disclaimers

By calling this project Juicemacs, I do mean that:

- It does not aim to become a solid implementation (yet).
- It is not bug-free ([[https://www.fda.gov/food/current-good-manufacturing-practices-cgmps-food-and-dietary-supplements/food-defect-levels-handbook][~5 Drosophila eggs per 250 ml]]).

Not written in Markdown, so it's shown here as plain text — view it formatted on GitHub.

emacs

Contributors

gudzpoz

347 commits

gudzpoz/Juicemacs

An absolutely-not-solid Emacs implementation (WIP)

Java

58

347 commits

updated Dec 22, 2025

See the code

README

#+title: Juicemacs - An absolutely-not-solid Emacs implementation

[[https://justforfunnoreally.dev][https://img.shields.io/badge/justforfunnoreally-dev-9ff.svg]]
[[https://openjdk.org/projects/jdk/25/][https://img.shields.io/badge/Java-25-orange.svg?logo=openjdk&ext=.svg]]
[[https://emacsen.de/dev/tests/][https://emacsen.de/dev/tests.svg]]
[[https://app.codecov.io/gh/gudzpoz/Juicemacs/][https://img.shields.io/codecov/c/github/gudzpoz/Juicemacs?label=coverage&ext=.svg]]
[[https://emacsen.de/dev/bench/][https://img.shields.io/badge/benchmark-charts-blue?ext=.svg]]
[[https://juice.zulipchat.com][https://img.shields.io/badge/chat-white?style=social&logo=zulip&ext=.svg]]

Juicemacs is a work-in-progress Emacs implementation +just for the fun of it+
that over-ambitiously aims to explore the following:

- Speculative JIT compilation
- Transparent(-ish) concurrentization of ELisp code
- Polyglot programming with Python, JavaScript, etc.
- GNU Emacs 30 compatibility

Java helps to make all these possible, for it runs on JVM, which happens to be a
platform with several nice things:

- A decent GC: HotSpot has a number of state-of-the-art GCs.
- Green threads & OS threads: One without the hassle of function coloring.
- An incredible JIT framework: [[https://www.graalvm.org/latest/graalvm-as-a-platform/language-implementation-framework/][Truffle]] lets you build an interpreter and a JIT
  compiler all at once.

Of course using Java brings in its own problems, which this project will need to
live with:

- Sloooow startup (and with Truffle, it actually needs two warm-ups)
- It bloats (and we can only hope Project Valhalla somehow tackles that)

* Running

Currently, Juicemacs has two functional interpreters (one for AST, one for
bytecode) and enough built-in routines implemented to handle =pdump=. It
usually stops when =top-level= tries to use unimplemented UI subroutines.

To run it:
1. Make sure to have JDK 25 installed (preferably [[https://github.com/graalvm/graalvm-ce-builds/releases/][graalvm-ce]]).
2. Clone the repository, go to [[file:elisp/emacs/]] and build a GNU Emacs to have
   all the generated data/elisp files ready.
3. Run =sh -c "cd app && $(./gradlew -q :app:jvmCmd)"= (in the project root) for
   a REPL.

#+begin_quote
If you're on Windows or just can't run the command above, it basically just does
the following:
1. Run the =:app:jvmCmd= Gradle task, which will produce a command with the
   correct JVM flags to make the JIT magic from Truffle work.
2. Run the produced command under the =app/= directory, because we currently
   hard-code the Emacs directory path to help with our tests. You can also use
   the =-L/--directory= option to specify a Lisp source directory.
#+end_quote

By the way, you may also try:
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --help"=
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --inspect=4242"= (for a [[https://www.graalvm.org/latest/tools/chrome-debugger/][Chrome
  DevTools protocol server]])

And specially, if you want to try out the experimental slowish pdump:
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --dump=pdump"=
- =sh -c "cd app && $(./gradlew -q :app:jvmCmd) --dump-file ./emacs.pdmp"=

We also support [[https://www.graalvm.org/latest/reference-manual/native-image/][Java native images]]:

- =./gradlew :app:nativeCompile= (pdump is much faster with native images)

** ERT Testing

Emacs comes with a unit-testing toolkit, Emacs Lisp Regression Testing (ERT),
and has a bunch of ELisp tests in its source repository (=./test/src/=).
Juicemacs currently can run some of these tests [[file:elisp/src/test/java/party/iroiro/juicemacs/elisp/ELispRegressionTest.java][with a bit of workaround]]:

#+begin_src elisp
  ;; TODO: pp requires a bunch of sexp parsing functions
  (require 'pp)
  (defalias 'pp 'princ)
  ;; ert asserts about newlines produced by pp
  (defun cl--assertion-failed (&rest _) t)

  (require 'ert)
  (load "../test/src/data-tests")
  (ert-run-tests-batch)
  (null (ert-run-tests-batch)) ; don't print the huge info object
#+end_src

You're welcome to try the tests and report any failing cases! (I think many of
them might simply throw an =UnsupportedOperationException= since they are yet to
be implemented.)

* Contributing

Check out [[file:CONTRIBUTING.org]] for a walkthrough. Check out [[file:docs/TODO.org]]
or search for =UnsupportedOperationException= or =TODO= in code for
things that need more work.

* Documentation

- [[file:elisp/README.org]]: Documenting the structure of the ELisp interpreter
- [[file:commons/piece-tree/README.org]]: Introduction to a [[https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation][piece tree]]
- [[file:docs/Notes.org]]: Reading list and notes for implementing this Emacs clone
- [[file:docs/Bytecode.org]]: Extracting (part of) the Emacs bytecode specs from
  Emacs
- [[file:docs/NativeComp.org]]: Looking into Emacs =native-comp= and how we can
  reuse it for a more efficient bytecode interpreter
- [[file:docs/TODO.org]]: TODO list & DONE list, tracking current/solved challenges

** Blog posts

- [[https://kyo.iroiro.party/en/posts/emacs-lisp-interpreter-with-graalvm-truffle/][Writing a Lisp JIT Interpreter with GraalVM Truffle]]
- [[https://kyo.iroiro.party/en/posts/why-rewriting-emacs-is-hard/][Why Rewriting Emacs Is Hard]]

* Similar projects

- https://github.com/remacs/remacs

- https://github.com/CeleritasCelery/rune

- https://github.com/federicotdn/pimacs

- https://codeberg.org/ramin_hal9001/schemacs

- [[https://www.cliki.net/cl-emacs][CL-Emacs]]: “Various people have proposed an emacs-like editor written in Common
  Lisp. This page collects together a few possibilities.”

- Also the discontinued [[https://jemacs.sourceforge.net/][JEmacs - the Java/Scheme-based Emacs Text Editor]] (source
  @ [[https://gitlab.com/kashell/Kawa/-/tree/master/gnu/jemacs?ref_type=heads][GNU Kawa]])

* Disclaimers

By calling this project Juicemacs, I do mean that:

- It does not aim to become a solid implementation (yet).
- It is not bug-free ([[https://www.fda.gov/food/current-good-manufacturing-practices-cgmps-food-and-dietary-supplements/food-defect-levels-handbook][~5 Drosophila eggs per 250 ml]]).

Not written in Markdown, so it's shown here as plain text — view it formatted on GitHub.

emacs

Contributors

gudzpoz

347 commits

Languages

Java

99.1%