A Clojure implementation on Chez Scheme.
Self-hosted compiler, Clojure-compatible standard library, no JVM.
Reads Clojure, analyzes it to a host-neutral IR, emits Scheme, and runs it on Chez. The compiler is written in Clojure and compiles itself.
A checked-in bootstrap seed runs on a fresh clone immediately. The build is a self-hosting fixpoint — a rebuild reproduces the seed byte-for-byte.
jolt build ahead-of-time compiles a project — runtime, standard library, app, and its deps — into a single self-contained executable. No Chez, no JVM, no source needed to run it.
future/promise/agent/pmap run on OS threads over a shared heap, matching JVM semantics. core.async provides channels and go blocks.
Exact integers and bignums, exact ratios ((/ 1 2) ⇒ 1/2), and flonum doubles. = is category-aware; == is value-equality.
Immutable vectors (32-way tries), cons lists, and HAMT maps/sets with Clojure value semantics. Transients are real mutable scratch collections.
Lazy/infinite seqs, transducers, destructuring, multimethods, protocols/records, metadata, namespaces, runtime eval, and the full reader.
Install the self-contained joltc binary — it bundles the runtime, compiler, and standard library, so there's nothing else to install.
# Homebrew
brew install jolt-lang/jolt/jolt
# or the install script (Linux / macOS)
curl -sL https://raw.githubusercontent.com/jolt-lang/jolt/main/install | bash
joltc -e '(+ 1 2)' # => 3
Or run from a clone (needs Chez Scheme) — no build step, the bootstrap seed is checked in:
git clone --recurse-submodules https://github.com/jolt-lang/jolt.git
cd jolt
bin/joltc -e '(+ 1 2)' # => 3
$ bin/joltc -e '(->> (range 10) (filter even?) (map (fn [x] (* x x))) (reduce +))'
# 120
$ bin/joltc -e '(/ 1 2)'
# 1/2
bin/joltc run -m myapp.core # resolve deps.edn, then run -main
bin/joltc -M:test [args] # run an alias's :main-opts
bin/joltc path # print the resolved source roots
bin/joltc build -m myapp.core -o myapp # single self-contained executable
./myapp arg1 arg2 # runs anywhere; args reach -main
# --opt for the optimized build, --dev for an unoptimized one
bin/joltc --nrepl-server # auto-resolves deps.edn, writes .nrepl-port
# connect CIDER / Calva / Cursive via the .nrepl-port file, then
# redefine a var and the next call sees it — no restart
Develop against a live process: see REPL-Driven Development.
Read the documentation for installation, writing libraries, and host interop.
Jolt targets Clojure semantics but runs on Chez, not the JVM. Most portable Clojure runs unchanged — persistent collections, the numeric tower, lazy seqs, transducers, multimethods, protocols/records, atoms, future/agent/pmap, core.async, runtime eval, and the full reader all behave as on the JVM. The genuine divergences:
| Aspect | Difference |
|---|---|
| Java interop | No JVM, so no general Java interop, reflection, or gen-class/proxy — a shimmed subset of java.* is available, plus a C FFI |
| BigDecimal | Not available (decimal? is always false); the rest of the numeric tower matches |
| Regex | Compiled by irregex, not java.util.regex — common patterns work, some Java-specific features differ |