# What is Clojure and how it is different from ClojureScript?

First, we'll briefly cover what Clojure is and how it works. After that, we'll see what ClojureScript is and how it's different.
 

## Note for readers
This article was written for those who are absolutely new to Clojure and ClojureScript and have a problem distinguishing what hides behind these two terms. It is not about nitty-gritty details.
This article was originally posted at [kozieiev.com](https://kozieiev.com/blog/clojure-difference-vs-clojurescript/).




## What is Clojure?
Clojure is a programming language that was created by [Rich Hickey](https://github.com/richhickey). His idea was to make a functional language that has strong concurrency support, and that works on Java Virtual Machine (JVM). Being a JVM-hosted language, Clojure has access to every platform that Java works on, with the ability to utilize a massive amount of preexisting code.



## What is JVM?
A basic understanding of JVM is helpful for understanding Clojure, so let's take a look at what the Java compilation process looks like:


![00-java-compilation.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660683431645/TuzSFclpC.png align="left")


In languages like C++, the compiler takes source code and turns it into a platform-dependent machine code that can be run by OS. Java is different, however. Its compiler takes `*.java` source code and compiles it into `*.class` files with **bytecode**. Unlike machine code, bytecode is a platform-independent format. So, Java compilers on different OSes will produce the same bytecode from the same source code. 

Then, JVM comes into play. Its class loader brings `.class` files to the RAM, verifies for security breaches, and finally, the internal JIT compiler converts bytecode to native machine code that works on the specific target platform where you run it.

So JVM is a set of tools that makes running bytecode on a target platform possible.



## What does "Clojure is a JVM-hosted Language" mean?
The two-step compilation shown in the previous section has two perks. First, the Java compiler doesn't have to know about machine code for different platforms; JVM handles that. 
Second, you are not restricted to using the Java compiler to get bytecode. You can write your own compiler that produces bytecode, and JVM can still run it.

And this is exactly the approach Clojure takes. Clojure doesn't have its own tools for generating machine code and running it on the target platform. Instead, it creates bytecode from Clojure sources and leaves the rest of the work for JVM. The diagram of the compilation process looks quite similar to the one for Java:


![01-clojure-compilation.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660683485872/bV3EllzWG.png align="left")



## Clojure compilation example

Let's run some example code (or just skip this section if you'd like).

If you don't have Clojure installed, please take a look at the [Getting Started](https://clojure.org/guides/getting_started) guide on the official site for instructions.

Then, create the following folder structure for a simplistic Clojure app:
```
project-dir        (project directory; choose any name you want)
├─ src             (in this folder, the compiler will look for sources)
│  └─ main
│     └─ test.clj  (source file with the main function)
├─ classes         (the empty folder, where generated classes will be stored)
└─ deps.edn        (configuration file)
```
Please make sure you've created an empty `classes` folder!

In `test.clj:`, we have a helloworld code:
```clojure
(ns test.main
  (:gen-class))

(defn -main []
  (println "Hello world!"))
```

`deps.edn:` contains configurations for the compiler. Here, we specify the sources folder:

```clojure
{:paths ["src"]}
```

Now, let's run the compiler from `project-dir`:

```bash
clj -M -m test.main
```
You will receive an output.
```bash
Hello world!
```

By default, you won't see the intermediate `*.class` files generated. But if you do want to take a look at them, run the `clj` command in the `project-dir`, and after it shows you a prompt, invoke compilation function:
```clojure
(compile `test.main)
```
Now, under the `project-dir/classes/test` folder, you will find the generated `*.class` files**. If you forgot to create an empty `classes` folder at the start, you'll encounter an error.



## What is ClojureScript?

When we refer to the term "Clojure," we usually mean both the programming language itself, as well as all its tooling. But let's look at these separately. 

There is a "Clojure programming language," meaning rules and syntax we use to describe how a program should work. Then, there is a "Clojure compiler," meaning a toolset that takes Clojure language as an input and turns it into Java bytecode.

When we make this distinction clear, it's easy to understand what ClojureScript is. It is a **compiler** for the Clojure programming language that turns Clojure code into JavaScript code. (not into Java bytecode as Clojure compiler does).

Just as Clojure allows you to utilize the power of functional programming in tasks and environments where Java is applicable, ClojureScript does the same for environments where JavaScript is applicable.

There is some difference in language support between Clojure and ClojureScript compilers. You can read more details about that on the [official site](https://clojurescript.org/about/differences)



## ClojureScript compilation process

Let's look at the ClojureScript compilation diagram. It's different from before, because JVM is missing.


![02-clojurescript-compilation.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660683503842/JMZBSQ4Dv.png align="left")

You will still have JVM running, because the ClojureScript compiler is written in Clojure, and as a Clojure app, it's run on JVM; But it is not essential here, because we can imagine an alternate world where the ClojureScript compiler is written in some other language.



## Google Closure Tools

You may be wondering what is `Google Closure Tools` on a previous diagram. Please note, the spelling is Clo**s**ure; not Clo**j**ure! It is a set of tools for JavaScript from Google. 

Google Closure includes a lot of useful JavaScript libraries. They are pre-packaged with ClojureScript, and can be used straight away. 

Also, there is a Google Closure Compiler that compiles JavaScript into optimized and minified JavaScript. ClojureScript uses Closure compiler when the optimizations setting is turned on.



## ClojureScript compilation example

Let's run some ClojureScript code. (As before, feel free to skip this section).

Here is the folder structure for our ClojureScript app:
```
project-dir        (project directory, choose any name you want)
├─ src             (in this folder compiler will look for sources)
│  └─test            
│    └─ main.cljs  (source file, notice that extension is *.cljs, not *.clj)
└─ deps.edn        (configuration file)
```

The main file is `test.cljs:`
```clojure
(ns test.main
(:require goog.string.format))

(println (goog.string.format "Hello %s" "world"!))
```
The `goog.string.format` function in our `test.clj` is absolutely not necessary for such a primitive app. I added it as an illustration of how easily you can use code from the Google Closure library in ClojureScript.

`deps.edn` contains a setting that tells that our project needs a ClojureScript package:
```clojure
{:deps {org.clojure/clojurescript {:mvn/version "1.10.758"}}}
```

Now, lets run the compiler from the project directory:
```bash
clj -M -m cljs.main --target node --output-to ./out/main.js -c test.main
```
As a result of the ClojureScript compilation, you will get a generated JavaScript file, `out/main.js`. It can be distributed and used in a JavaScript environment. For example, with `node`:

```bash
node out/main.js
```
You should see the output,
```bash
Hello World!
```



## Note on compiler arguments

You may be confused by the fact that the command-line arguments for running Clojure and ClojureScript compilers are quite similar, and invoke the same `clj` command. Take a look:

```bash
clj -M -m test.main
clj -M -m cljs.main --target node --output-to ./out/main.js -c test.main
```

This is because the ClojureScript compiler itself is written in Clojure! 

So, in the first example, we ran our code, `test.main` namespace, as a Clojure app. Similarly, in the second example, we ran `cljs.main` namespace, which is a ClojureScript compiler app, and passed additional arguments to it as instructions on how to compile ClojureScript.



## Conclusion

  - Clojure is a functional programming language.
  - The Clojure compiler turns Clojure sources into bytecode and runs it on the JVM.
  - ClojureScript is another compiler for Clojure language that takes source code and compiles it into JavaScript language.


[![bmc-button.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1660734072378/aFKIVs0VE.png align="left")](https://www.buymeacoffee.com/volodymyrk)


## Related YouTube videos:
%[https://youtu.be/psW6-DB0FlA]

%[https://youtu.be/ABQk9iMUypY]

<script type="text/javascript" src="https://cdnjs.buymeacoffee.com/1.0.0/button.prod.min.js" data-name="bmc-button" data-slug="volodymyrk" data-color="#FFDD00" data-emoji=""  data-font="Poppins" data-text="Buy me a coffee" data-outline-color="#000000" data-font-color="#000000" data-coffee-color="#ffffff" ></script>
