Mixing reagent and and re-frame in non-SPA - crazy?

I have developed a server-side Clojure app and have only played around with Clojurescript / Re-frame. But I am now preparing to make a transition into Clojurescript and feel like there are lots of important decisions that have to be made. First of all, Shadow-cljs or Figwheel-main? This post is not about that choice but I just want to give an example of exactly how early in the process I am.

The application that I will be developing is essentially an administrative interface to a database. So a lot of pages where the user basically checks checkboxes, enters values, creates new entries etc. There is some client-side logic for validating input and sometimes retrieving data from the server. And then there are a couple of more complex views where users can build reports of the data.

A full-blown SPA seems too advanced for this use-case. There seems to a lot of overhead with managing the browser history, gracefully handling reloads, handling conflicts between client- and server side data, etc. It seems a lot simpler to render most HTML server-side and send along some Clojurescript code to handle client side logic. Reagent seems to be a good general fit for this. However, I really like Re-frame (mostly from reading the re-frame readme) and I think that it may be suitable for the more advanced views. My reading of various blog posts suggests that when there are a more than a few components on a page that need to be synchronized, decentralized state management with reagent quickly becomes very complicated.

So, I guess that my questions are:

  • Is it a feasible/good idea to mix reagent/re-frame in a mostly server-side application? Are there any examples of non-SPA re-frame apps?
  • How does one go about having different “entry points” into the Clojurescript code in different server-side rendered pages? Most examples I have seen are SPAs where the client resolves the URL to determine what to do, or just single page examples where there is only one entry-point. Any examples would be very welcome.

I would be extremely grateful for any help! Please let me know if I can clarify in any way.

Your logic is fine, your concerns are rightly placed, and nonetheless you will eventually wind up making a SPA! It can be simpler for 1 program (the cljs) to make and maintain the HTML, than for 2 programs (server and client) to divide the responsibility. As soon as you’ve programmed your first serious drop-down suggestion box in cljs, you’ll see that the HTML page scaffolding sent by the server was not really all that great a boost. You are not in JQuery-land anymore. If 100% of the HTML is made in the browser, then the server side can focus on being a webservice - and suddenly you can do reasonable server tests with curl. Meanwhile, the automatic code reload for cljs projects makes cljs surprisingly un-burdensome to work with.

1 Like

Thank you for your response @Phill! I think that you may very well be right. Do you then also think that it should be re-frame all the way, not some parts with simpler reagent logic?

Are there good examples of “full stack” re-frame SPAs with routing, offline handling, dirty forms, authentication, authorization, specs, etc.? Or preferred libraries for these?

I guess that it also unclear to me what exactly a fullblown Clojurescript SPA looks like. Since I am used to server-generated HTML + jQuery, just as you mentioned.

I found purelyfunctional.tv very helpful, getting started with ClojureScript SPAs. A foothold in the quicksand, as it were. After that, it’s just programming.

In the same vein, I might try first with just plain Reagent. Fred Brooks famously said, “Plan to throw one away,” and experts now believe that he had everyone’s-first-SPA in mind. If your Reagent page logic gets so twisted you must redo it, then hop over and redo it in Re-frame. It’s kind of bizarre, but it really works.

1 Like

This might be a good example: https://github.com/jacekschae/conduit

It’s a re-frame based implementation of the RealWorldApp frontend.

1 Like

Totally fine for me.
I prefer classic MPA with react when appropriate.
I use rum instead of reagent/re-frame, no problems with server-side rendering.

I use single entry point or multiple cljs builds, so “it depends”.
Example of my application template is available here https://github.com/serioga/webapp-clojure-2020

1 Like

This is true, I am very used to jQuery and maybe I just need a mindshift.

That sounds like a good idea to start small and advance to re-frame if/when it becomes unwieldy.

@Phill, @mvarela, @Serioga: Thank you for the resource tips! I’ll check them all out.