Emacs-first · standard ECMAScript · v0.1.1 · npm · GitHub

Eliscript

A 100% Emacs Lisp-compatible core with 1+5+2 explicit extensions, persistent values, a self-hosted compiler, and four-target execution across Emacs, JavaScript, WASM, and ARM64 Native.

175stable specifications
598checked library exports
35/35core criteria retained passing
0tracked .mjs source files

One language, two compiler generations, four execution targets.

Plain Emacs runs the 100% compatible core and builds the seed. The seed builds the self-hosted Eliscript compiler across stage0–stage3, emitting readable, source-mapped ESM alongside zero-glue WASM and ARM64 native binaries.

01

Read Lisp

Parse Emacs Lisp forms, 1+5+2 extension packs, persistent literals, modules, macros, and explicit host boundaries.

02

Prove semantics

Expand deterministically, check static contracts and pre/post assertions, validate transient ownership, and verify tail recursion.

03

Lower explicit IR

Seed and self-hosted stage1–stage3 compilers produce identical versioned IR, diagnostics, and Source Map v3 locations.

04

Run across targets

Execute identically in Emacs Lisp, standard ESM (Bun, Node, browser), and zero-glue WASM / ARM64 native `:abi` targets.

Small forms, strong guarantees.

Switch between language mechanisms. The right pane describes the behavior the compiler and runtime preserve across Emacs and JS hosts.

language / executable semantics
Eliscript
(defun sum-to (n total)
  (if (= n 0)
      total
    (recur (1- n) (+ total n))))
Runtime contract
tail position verified
arguments evaluated once, left to right
function frame reused as a loop
constant JavaScript stack

100% Emacs Lisp core + 1+5+2 explicit extensions.

Standard Emacs Lisp works unchanged by default, while seven modular extension packs add static contracts, persistent data, unified destructuring, lexical modules, structured async, explicit JS sentinels, and multi-backend native ABI lowering.

Emacs Lisp Core + Contracts

Lisp-2 & static declarations

100% Emacs Lisp default semantics (Lisp-2, nil-only falsiness, integer division, condition-case, pcase) plus opt-in declare type, purity, and pre/post contracts.

Persistent data (Pack 2)

Share structure, not mutation

7 persistent collections (List, Vector, HAMT Map/Set, Queue, AVL Sorted Map/Set), cl-defstruct-persistent with JSON Schema round-trip, state-cell, Transducers, and Transients.

Destructuring & Control (Pack 3)

Unified pcase superset

defun-case multi-arity dispatch, let-bind / defun-bind / pcase-value destructuring, let-const, 50,000-depth recur, thread-some->, and fn-* combinators.

Modules & Macros (Pack 4)

Lexical privacy & pure macros

defmodule with lexical-private bindings, explicit :export / :import, and defvar-once hot-reload state, plus sandboxed defmacro-checked.

Async & JS Interop (Packs 5–6)

Structured concurrency & sentinels

defun-async / await, with-async-scope cancellation, backpressure async-channel, handle revocation, and lossless js-false / js-null / js-undefined sentinels.

Multi-Backend ABI (Pack 7)

Emacs · JS · WASM · Native

Explicit :abi (:numeric-f64 / :memory-u32) declarations and linear-memory operators execute with identical results across Emacs, ESM, WASM, and ARM64 native binaries.

The maturity baseline is real. The language keeps moving.

All 42 implementation units, 35 mandatory verification criteria, and 173 stabilization units are complete in the retained core evidence. Future work is tracked without retroactively inflating that result; general automatic tail-call optimization begins as a Draft and Pending specification.