How I made the world's worst clojurescript REPL
Tags: node, clojurescript, clojure, atom
Published: 2019-05-09 16:36:47

---
title: How I made the world's worst clojurescript REPL
published: true
description: Clojure-focused software engineer makes a clojurescript repl 🤔
tags: node, clojurescript, clojure, atom
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pl1hbpyeu5lbnwwd6gyc.jpg
---

**TL;DR**
I tried to run two clojure web servers and call a JSON endpoint and the JVM fell over on my [cheap 512 MB VPS server](https://www.vultr.com/?ref=7614094), so I switched to clojurescript and wrote my own prepl client for atom

## My clojure deployment workflow in a nutshell

I use atom in vim mode for clojure development and I made something cool, something for all clojurists to enjoy! The idea is to scrape conference websites, and get json from the HN api, the clojureverse api and the reddit api for clojure related news and put it all on one website. I'm not really an expert at all things JVM, but I know enough to be dangerous with clojure:

- build the classpath
- compile to bytecode 
- make sure you have a `-main` function

…those sorts of things. Unfortunately, I did what I normally do with a twist, instead of building a whole uberjar, I simply compiled to bytecode with the help of [this post](https://cjohansen.no/clojure-in-production-tools-deps/). I then put it on my 512 MB VPS server and it won’t even do the thing where it downloads some json. It runs for a while and then unceremoniously reports back… **Killed**.


## My Cheap VPS Dreams Were *Killed*

That’s it, that’s all the process says, no exceptions, nothing, just killed. I set the JVM to only use 100 MB of RAM but not even that is enough on a VPS running two other JVMs (in addition to two clojure REPL servers). I decided then and there that I had had enough, I decided to switch to clojurescript on the server. Surely v8 uses less resources than the JVM running clojure and [my full stack framework coast](https://coastonclojure.com) 🙄

In my side projects I don't look for *solutions*, I look for *excuses*.

## How does clojurescript in node.js even work?

Now having the perfect excuse to switch the project to clojurescript, the question is how do I get my current atom repl client [chlorine](https://github.com/mauricioszabo/atom-chlorine) working with clojurescript? Wait, back up a second… how do I even get clojurescript running on node to begin with? 

[DDG](https://duckduckgo.com) to the rescue!

Here's the breakdown of the clojurescript tooling landscape as I understand it. There are three major ways to get your clojurescript files compiled down to js so that node can understand them:

- [shadow-cljs](http://shadow-cljs.org)
- [Lumo](http://lumo-cljs.org)
- [clj](https://clojurescript.org/guides/quick-start#running-clojurescript-on-node.js)

I'm not supposed to give my opinion but…

- shadow-cljs looks like lein and after tools.deps I'm not crazy about the sheer amount of edn I have to understand to get projects working, especially since node is supposed to be as easy as `node index.js`
- lumo looks interesting, but I'm not sure what I gain from using self hosted clojurescript vs the clojure bootstrapped version
- clj is familiar to me and it looks so simple, just write a `build.clj` file like this:

```clojure
(ns build
  (:require [cljs.build.api :as b]))

(b/build "src"
  {:output-to "main.js"
   :output-dir "target"
   :optimizations :simple
   :target :nodejs
   :main 'your-project.core})
```

and run it with `clj build.clj`. It doesn't get much easier than that, I didn't even have to install anything other than clojure!

So, now that I've settled on `clj` I can use chlorine and… oh wait, [it only supports lumo and shadow-cljs](https://github.com/mauricioszabo/atom-chlorine#how-to-work-with-clojurescript). At this point, a sane person would say ok I value my free time, I'm going to just use one of those and I can continue on to my real goal of putting out this clojure website for aggregating clojure info in one place. If you've gotten this far you know I'm not a sane person.

## Insane in the membrane
I want to run this in my terminal:

```bash
clj -J-Dclojure.server.node="{:port 5555 :accept cljs.server.node/prepl}" -m cljs.main --repl-env node
```

and I want atom to do the right thing: connect to it and allow me to send bits of clojurescript code to it. I don't know why this is so complicated, clojure is supposed to be SIMPLE. Eff.

…Stay tuned for my next post where I talk about all things atom package development and how I switched from plain old javascript to clojurescript grudgingly just to read the EDN from the prepl server.