Embeddable
One createSession() call gives you a sandboxed Clojure runtime in any JS/TS project. Inject host capabilities, evaluate strings.
A Clojure interpreter that lives inside JavaScript. Embed it, REPL into it, give it to your LLM.
The snippet below is evaluated by cljam in your browser when you press Run. Edit it, re-run it, break it. It's the same interpreter that ships on npm.
Try editing the Playground for a full Monaco-powered REPL with multi-form evaluation, persistent state, and sample files.
Drop a Clojure runtime into any JS/TS project. createSession() returns a plain object. Evaluate strings, hand the same session to an editor, give it to a tool call.
import { createSession, printString, nodePreset } from '@regibyte/cljam'
const session = createSession({ ...nodePreset() })
const result = session.evaluate('(map inc [1 2 3])')
console.log(printString(result))
// => (2 3 4)Inject your own host APIs through hostBindings and Clojure code can call straight into your TypeScript world. See the Embedding guide for the full surface.
cljam ships a real nREPL server, the same protocol Clojure tooling speaks officially. Install once, run once, and Calva / CIDER / Cursive will treat your Node or Bun process like any other Clojure runtime.
npm install -g @regibyte/cljam
cljam nrepl-server --port 7889 --root-dir .Now evaluate forms straight from your editor against a live JavaScript process. Pair this with cljam-mcp and an LLM gets the same view of the same session you do.
(require '[cljam.schema.core :as s]
'[cljam.date :as date]
'[cljam.integrant :as ig])
(s/validate [:map [:name :string] [:age :int]]
{:name "John Doe" :age 36})
;; => {:ok true :value {:name "John Doe" :age 36}}
(date/format (date/now) "de-DE" {:year "numeric" :month "long" :day "numeric"})
;; => "17. April 2026" (formatted date string)Each library is a regular npm package under the @regibyte scope. Build your own with cljam gen-lib-source. See the Building Libraries guide.
"In February 2026, I had a question that had been sitting in my mind for a long while: how does an interpreter actually work? Not just the theory."
cljam started as a learning project, one that taught me many things. I hope it may be useful or interesting enough for you to give it a try. If you're curious about the architecture, the bugs uncovered along the way, or why a Clojure dialect in TypeScript is even a thing, read the build journey.