What are paradigm differences between different front-end ClojureScript libraries?

clojurescript

#1

What are differences between paradigms and approaches of different UI libraries and frameworks. For example there are Rum, Om Next, Re-frame/Reagent, Fulcro, Hoplon. These all are promising. I am a beginner in Clojure(Script) space. I want to find out how do they do things differently from each other. Kindly share your experience and advice.


#2

I would say that Rum and Reagent (not Reagent+Re-frame) are quite similar with one big difference: Reagent supports server-side rendering with ClojureScript/Node.js and tries to play really well with the React/Javascript/npm ecosystem (easy to use existing React components from npm), Rum supports server-side rendering in Clojure/JVM, which means you can’t use React.js components from npm on the server at all. (I have only used Rum seriously).

My understanding of Fulcro is that it’s a friendly fork of Om Next, with better documentation and a few different design decisions.

All of them are React.js wrappers with some “sugar” on top. Rum/Reagent are pretty close to React.js itself, only providing a way to make them reactive to some atom. Re-frame adds better state/logic management on top of Re-frame (and Citrus does roughly the same for Rum). Om Next/Fulcro tries to make data dependencies of React components declarative in the components themselves, based on a unified graph database.

Hoplon is in its own category. It kinda replicates the concepts of Excel/spreadsheets cells/formulas to the UI, where data go into cells, and derived data/UI/other side effects goes into formula cells. It uses its own rendering stack (maybe based on jQuery? I don’t remember). Take this with a grain of salf, it’s been quite some time I haven’t looked at it.

Hope this helps!


#3

Reagent and Re-Frame are close conceptually to React and Redux. Their general approach is more or less along the lines of what a React programmer would expect, except that functional programming is more built in to the ClojureScript language. The learning curve is a lot lower than Om Next or Fulcro.

Om Next and Fulcro, on the other hand, are big paradigm shifts. They use co-located queries to keep components relatively self contained. Components just say what they need. They’re able to take a tree of data and convert it to a normalized database using idents. On larger projects that use Redux, you can face decisions about whether to duplicate data in one of your reducers (decoupling and denormalizing them) or use Redux’s connect function to reach out across your application to get data from a reducer for another feature. But then you’ve tied two far-flung parts of your application together. Using Om Next or Fulcro allow you to think more locally within your components.

I’ve also noticed that Om Next and Fulcro also use the code-as-data approach more heavily, which pays off in terms of simplifying client-server communication. Om Next and Fulcro require a stronger knowledge of ClojureScript than Reagent/Re-frame, since things like syntax quoting and multi-methods tend to be used more.

Fulcro is built on Om Next, and it takes care of a lot of things you would need to do yourself if you were to use Om Next. It’s a bit more opinionated. But it also has much more extensive documentation and a nice template with dev tools and a backend server. One misconception I had early on was that Om/Om Next was tied to Datomic, which caused me to look elsewhere for a while. But that is fortunately not true. Works great with Postgres and Walkable.

Rum looks nice, but when I tried to use it, I ran right into an open bug around controlled inputs which I needed for my use case.

It’s probably evident that I really like Fulcro/Om Next. But I would recommend using Reagent to anyone getting started with Clojure(Script).


#4

I ended up going with fulcro after looking a while at the different alternatives.
Some personal thoughts on the cljs front-end libraries:

Hoplon
Is something different not a react wrapper.

Rum
Seems interesting but very minimal wrapper. The thing that sets it a part is that it can do SSR on the JVM. Think only rum, om-next & fulcro have nice server side rendering on the JVM out of the box.

Reagent
Is a minimalist wrapper. Think it’s great for getting started and being productive but you do have a lot of blanks to fill. There is also a nice free course https://learnreagent.com/

Re-frame
Think it’s the most popular library. If you’re just getting started the docs are really nice, seems pretty close to redux/mobx, docs are awesome & plenty of libraries available.

Keechma
Reagent based framework close to re-frame. Has some interesting concepts centered around the router.

Om-next
Interesting conceptually. Would even go as far as calling it “ground breaking”. But mostly unmaintained, docs missing and nothing much happening there apart for bug-fixes. If you like the concepts there really is no reason to not go with fulcro.

Fulcro
This is the one I ended up using. Fulcro, previously named untangled started out as a om-next fork now it’s standalone.

It’s close to apollo-client in js, but a lot less restrictive (ex: you have full access to the app state like in redux)

There is a bit of a learning curve, but if you have the time would recommend learning it if nothing else just to learn from it since it has a really nice architecture (for me reading the fulcro docs was similar to learning clojure, plenty of “AHA, wow” moments when I realized how beautiful & consistent all the pieces fit together).

I really liked the answers in fulcro for problems I was having:

  • How do you normalize you app state ? (ex: if you’re duplicating the article in 3 different views you can only go so far)
  • How do you handle fetching only the data you need from the server ? (ex: adding a new server property on the component should propagate to all the views in witch the component is used)
  • How do you do optimistic updates right ?
  • How can I take advantage of a graphql backend like apollo-client does ? (not out of the box, you have to integrate with https://github.com/wilkerlucio/pathom , but works really nice)

To sum it up. If I had to start all over I would go with:

Reagent for moving fast on toy apps.

Re-frame or Keechma for moving fast on mid sized apps . Pretty sure they also scale ok but you still have some things that you have to implement yourself (normalization, fetching only the data that is needed etc…)

Fulcro if you have the time and are looking for something that after you learn will help you with a lot of the heavy lifting, moving a lot of the complexity away from your app code.