How to use the online Clojure compiler
- Write or paste Clojure code into the editor. Reset example brings back the starter program with a factorial, a sorted list of maps,
frequenciesand a->>pipeline. - Press Run or use Ctrl + Enter (⌘ + Enter on a Mac).
- Text printed with
printlnappears in the Output panel. After the run, the value of the last form is printed as=> ...in readablepr-strform. If that value isnil, for example when the program ends withprintln, nothing extra is shown. Errors are shown with their message. - Choose a time limit of 5, 15 or 60 seconds, or press Stop to end a run early.
On the first run the page downloads the interpreter, about 1 MB. Copy and main.cljs save your code, and A−/A+ change the text size.
Everything runs in a Web Worker in your browser. Your code is never sent to a server. The editor auto-saves your last program in your browser, separately for each compiler.
About Clojure, ClojureScript and SCI
Clojure is a modern Lisp built around immutable data structures and functional programming. The original Clojure runs on the Java Virtual Machine, and ClojureScript is the version that targets JavaScript. This page uses Scittle 0.8, which packages SCI, the Small Clojure Interpreter, for the browser. SCI interprets your code directly with ClojureScript semantics, with no JVM or build tool involved.
What's supported
- Definitions and control flow:
def,defn,fnand#(...)literals,let,if,when,cond, andloop/recur. - Persistent collections: maps, vectors, sets and lists, keywords, and destructuring in
letand function arguments. - Sequence functions, including
map,filter,reduce,sort-by,group-byandfrequencies, plus lazy sequences such asrangeanditerate. - Threading macros
->and->>, and atoms for managed mutable state. - JavaScript interop in ClojureScript style, as in
(js/Math.sqrt 16)or(.toUpperCase "abc").
Limitations:
- No JVM interop. Classes like
java.util.DateorThreaddo not exist. - No Leiningen or deps.edn. External libraries cannot be added, so only the code in the editor and the built-in namespaces are available.
- No input box and no DOM. Define your test data in the program.
Worked example: immutability and threading
(def inventory {:apples 3 :pears 0})
(def restocked (assoc inventory :pears 12))
(println inventory) ; {:apples 3, :pears 0} (unchanged)
(println restocked) ; {:apples 3, :pears 12}
(def counter (atom 0))
(dotimes [_ 5] (swap! counter inc))
(println @counter) ; 5
(->> [3 8 1 9 4]
(filter odd?)
(map #(* % 10))
(reduce +)) ; => 130
assoc returns a new map and leaves the original unchanged. When you need a value that changes over time, keep it in an atom and update it with swap!. The last form is a ->> pipeline. It passes the vector through each step as the last argument, and its result is printed as => 130. Use -> instead when the value should be the first argument, as with assoc and update on a map.
Differences from JVM Clojure and common pitfalls
- Numbers are JavaScript numbers. With ClojureScript semantics there are no ratios or big integers.
(/ 1 3)returns0.3333333333333333, and very large integers lose precision. - There is no separate character type. A character literal like
\ais a one-letter string, so(frequencies "mississippi")has string keys. - Laziness hides side effects.
(map println xs)may print nothing if the result is never used. Usedoseqorrun!for side effects. - Infinite sequences.
(range)anditeratenever end, so always limit them withtake. If you print an infinite sequence, the run continues until the time limit stops it. printlnvsprn.printlnprints strings inside collections without quotes.prnkeeps the quotes, which makes data easier to read.
Frequently asked questions
Is this real Clojure?
It is Clojure code run by SCI with ClojureScript semantics, not the JVM implementation. The core language, collections and sequence library work the same way, so most pure Clojure code runs unchanged. Java interop and JVM-specific behaviour do not work.
Can I add libraries or use a project file?
No. Leiningen, deps.edn and Maven dependencies are not available. Each run interprets the single file in the editor.
Why is the file called main.cljs?
Because the code runs with ClojureScript semantics. You can paste the contents into a .clj or .cljc file, as long as it does not rely on JavaScript interop.
Which other languages can I try?
The online Scheme interpreter is another Lisp to explore. For JavaScript itself, use the online JavaScript compiler, or see all online compilers.