7 GUIs in ClojureScript: Setup and Counter
I discovered the 7 GUIs benchmark via a Twitter thread on hiring developers and wanted to implement it in ClojureScript.
In 7 GUIs, each task is a self-contained app with clearly defined functional requirements and a few guidelines for a good solution. The apps get more complex as you go, and each explores different problem areas that are common in UI programming.
I’ve been doing toy projects with Clojure for a while, and I have tried ClojureScript a few times in the past, but I fell victim to analysis paralysis every time and never got too far. Luckily, I found Jacek Schae’s excellent Learn Reagent course last year, with clear and modern guidelines for structuring, developing, releasing and deploying a ClojureScript app. I can now concentrate on solving the 7 GUIs instead of tooling or code organisation issues.
The first problem
As I was ready to tackle the first task, I could not find a Create React App equivalent for ClojureScript projects: a single “starter pack” used by most developers.
I liked the simplicity of the “Learn Reagent” setup and wanted something similar. The author has a few templates on their Github. Still, I thought I needed something slightly different: no additional dependencies (like Tailwind CSS or Firebase) and baked-in support for CIDER nREPL needed for my editor setup.
I ended up creating my own starting point repository, which wasn’t on the plan. But at least I learned more about how the base tools work together.
The “Counter” task
The counter app is very straightforward to implement; here’s my take and the code. Many templates and “Getting Started” guides have a similar UI as an example.
Even though the functionality is very simple, I implemented the counter as a separate component. I didn’t think it was necessary to create a different namespace for views, so it lives in the main namespace for the app.
The state is local to the component because it’s only used there. I like the idea behind Reagent atoms: they’re just like regular Clojure atoms, but any UI components that deref them are re-rendered whenever the value of the atom changes.
I think this implementation fulfils the requirement of having “almost no scaffolding”.
I want to keep these posts short, so I’ll publish my thoughts on the rest of the tasks in multiple articles:
- 7 GUIs in ClojureScript: Setup and Counter
- 7 GUIs in ClojureScript: Temperature Converter, Flight Booker
- 7 GUIs in ClojureScript: Timer, CRUD, Circle Drawer