Deborah Emeni I'm a software developer and technical writer who specializes in Node.js and JavaScript.

Getting started with ClojureScript for JavaScript developers

4 min read 1364

Getting started with ClojureScript for JavaScript developers

When creating web applications, developers can use functional programming, which offers benefits such as data immutability, concurrency, stability, and scalability. Functional programming is best supported by languages like Clojure but not by JavaScript. The good news is that ClojureScript compiles Clojure code into JavaScript, which can be executed in a browser or Node.js.

In this article, we’ll learn about ClojureScript, its advantages over Vanilla JavaScript, and its differences from other languages. The included code samples will show you how to get started and create a program with ClojureScript on your local machine.

Jump ahead:

Prerequisites

To follow along with this tutorial, you’ll need:

What is ClojureScript?

ClojureScript is a compiler for Clojure that compiles to JavaScript and creates web applications. The difference between ClojureScript and Clojure is that Clojure targets Java-based environments, while ClojureScript targets JavaScript.

Programs written in Clojure can be compiled to or emit JavaScript code using the ClojureScript compiler, which also supports JavaScript libraries. Essentially, ClojureScript combines JavaScript’s interoperability with Clojure’s vast benefits. Hence, ClojureScript compiles to JavaScript code and runs in the browser or Node.js.

ClojureScript uses the Google Closure tool, which manages libraries and dependencies and also minimizes code size. It’s important to note that with ClojureScript, code is stored as data. At the time of writing, the latest version is v1.11.60.

Benefits of ClojureScript over Vanilla JavaScript

ClojureScript offers several advantages compared to other apps that only use JavaScript, including:

  • Simplicity: ClojureScript belongs to the Lisp family of languages. It has a less verbose syntax and a more code-centric appearance. Its simplicity gives it power and speed
  • REPL: ClojureScript enables REPL-driven development by providing easily accessible REPLs for many JavaScript environments. REPLs let you continuously run code and get feedback right away without manually starting a compile-build-run cycle
  • Atoms: atoms are a type of data in ClojureScript that manage shared, synchronous, and independent states. They are immutable value containers that can only hold one but can swap their values. Because of these atoms, you can still see when state shifts occur. This is useful for dealing with states that vary over time
  • Interoperability: because ClojureScript supports interoperability, it is simple to use existing JavaScript libraries

How ClojureScript differs from languages that compile to JavaScript

Although multiple languages can be compiled in JavaScript, ClojureScript has some major differences when compared to the others. Let’s take a look:

CoffeeScript vs. ClojureScript

CoffeeScript is like Python and Ruby and has a straightforward syntax that aids in development. Its primary goal is to increase productivity by reducing verbosity. However, ClojureScript increases the program’s overall speed while CoffeeScript does not.

Dart vs. ClojureScript

Dart is a type-safe language that makes apps for several platforms and compiles to JavaScript. It was developed by Google to replace JavaScript and has a verbose syntax. However, ClojureScript, which supports the code as data philosophy, has a significantly more straightforward syntax that is understandable by both humans and machines. As a result, it has a robust macro system.

TypeScript vs. ClojureScript

While TypeScript and JavaScript have comparable syntaxes and semantics to ClojureScript, they differ from one another. In essence, TypeScript is static-typed JavaScript and inherits almost all of JavaScript’s issues. Unfortunately, layering a type system can only go so far as to address those issues. While JavaScript carries the baggage of having bad semantics and other issues, ClojureScript is a superior language because it yields more reusable code.

PureScript vs. ClojureScript

Similar to how TypeScript compiles to JavaScript, PureScript is strictly functional and rigorously typed. PureScript is written in Haskell and has a Haskell-like syntax, but was created to work with Node.js while ClojureScript is written in Clojure.

Setting up a demo project with ClojureScript

Next, we’ll start configuring ClojureScript for our project. Make sure that you have installed the prerequisites.

Setting up your project folder for ClojureScript

Depending on your OS, there are different requirements for installing ClojureScript. To find the installation commands that work with your OS, consult the official documentation. For simple project interaction, ClojureScript offers REPLs.

Create a directory to host your project to use ClojureScript. Then, launch your terminal and enter:

mkdir clojure-program

Creating the namespace and ClojureScript file

By permitting and implementing modularity through namespaces, ClojureScript enables you to logically arrange functions and variables for later use inside your program. Declaring namespaces and referencing functions in modules is easy if your project follows the naming convention. To do this, we’ll make a unique namespace for this project.

Create an src folder in the directory using your favorite code editor to store the project’s source code. Then, inside of your src, make a new folder named cljscript_program that will hold your app.cljs ClojureScript file.

Then, in the app.cljs, make a namespace with the ns keyword and the filename that produces the following message:

(ns cljscript_program.app)
(println "My first ClojureScript program!")

Creating the file for dependencies

Next, make a deps.edn file in the project directory with a list of every dependency that your project has. ClojureScript is the sole dependency you’ll use for this program.

{:deps {org.clojure/clojurescript {:mvn/version "1.11.54"}}}

Running the ClojureScript program

The cljs.main namespace is required to run your ClojureScript program. It contains functions with multiple usecases to initiate an interactive REPL session. Depending on the task, you can access and specify numerous arguments and flags with cljs.main.

Run the following command to see a list of available command-line arguments:

clj -M -m cljs.main --help

The arguments will be listed in your terminal once you run the command:

Listed arguments in ClojureScript terminal

To compile, run, and launch an REPL session for your ClojureScript program, run the command in the project directory for your OS.

For Windows OS, run this command:

java -cp "cljs.jar;src" cljs.main --compile hello-world.core --repl

For macOS or Linux OS:

clj -M --main cljs.main --compile cljscript_program.app --repl

Let’s review the arguments we specified:

  • --main: specifies and invokes cljs.main, which contains the functions needed to run your program
  • --repl: starts an REPL session allowing you to communicate with your program while it is executing
  • --compile: Builds your program

Following the program execution, .cpcache and out will be generated in the project directory, and an REPL session will launch in the terminal. We should also write the following to the prompt as the string My first ClojureScript program!:

Starting the ClojureScript program

It will display a browser window at localhost:9000:

Browser displayed at localhost:9000:

Now that your program is up and running, you can write code and interact with it via the REPL.

Creating a ClojureScript function

Using the defn naming function, create a ClojureScript function in app.cljs that returns the total of two numbers and binds to the variable total:

(defn total [x y]
   (+ x y)
)

You’ll require the following clauses to run your program and communicate with it in your REPL:

  • require: lets you define how many namespaces to load
  • :reload: loads the namespace
  • :as: enables you to specify a shorter version name to be used as a namespace reference

There are various methods in ClojureScript for requiring your namespace. Run the following command from the REPL prompt:

(require '[cljscript_program.app :as cljscript] :reload)

This command requires and creates the alias cljscript, then reloads your namespace.



After that, use the alias as a reference to invoke the function defined in your namespace.

(cljscript/total 20 40)

You should see 60 displayed in your terminal after selecting the enter key at the prompt:

ClojureScript terminal prompt

Conclusion

In this article, we investigated ClojureScript and its advantages over Vanilla JavaScript. We covered how ClojureScript differs from CoffeeScript, Dart, TypeScript, and PureScript in how it compiles to JavaScript. We also showed how to install and run a ClojureScript program.

: Full visibility into your web and mobile apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.

.
Deborah Emeni I'm a software developer and technical writer who specializes in Node.js and JavaScript.

Leave a Reply