Jive for Artisanal Software

Hi everyone! I wrote a blogpost about an architecture where UI code is server-rendered but still web-based. This enables native backends with the reach of web. Give it a read and share your thoughts!



I like the write-up.

A few thoughts:

  1. Could the vDOM still live on the client? Imagine a client side vDOM that exposes the vDOM to the server through some mapping from vDOM client side object to server custom representation. And the server manipulates its view of it, then sends it to the client, which will map it back into its own vDOM format and do the diff against the current vDOM and then update the DOM.

  2. As much as people say it sounds a simpler model, I still wonder… Seperating your UI logic from your business logic still makes sense. So to me the real problem is more with regards that people have to use JS for their UI work, and that has a terrible bundling and delivery mechanism. As an example, even on the desktop, people have created architecture that are client/server. So I always wonder if the hard part isn’t just that building UIs is hard, even if you move it to the server. There are no “liked” server side UI framework either lol, people hate QT, they hate WPF, they hate Cocoa, they hate Swing, etc.

  3. Could be interesting to look into Blazer server side rendering and SignalR (which I understand is similar to Phoenix Live View). Also curious if Clojure CLR can be used for it.

Those are my thoughts for now.

I’ve been using a somewhat similar architecture in our applications:

  • Server side generates a spec of what the UI should look like - eg a list of specifications for fields that should be rendered - just maps and vectors.
  • This spec is then passed to a data loader that loads all data required for the spec to display
  • The spec and data then gets sent to client side, which only knows how to render each field and doesn’t know anything about business logic

There are some optimizations to this process (eg only send a diff instead of the entire spec, use server side events to push the diff to the client side after each transaction).

The benefit of this architecture is that the business logic sits server side and it requires very little changes on the client side. I’ve used the same front end code for lots of different applications. Even nicer is that if I work on the client side, for example by adding a new type of field, it benefits all of my applications.

I’ve been very happy with this architecture, as it allows for a very declarative way of building applications.

1 Like

How good of a UX do you end up with here? Are your applications mostly forms input/output?

I think the UX is pretty good, at least for our purposes.

Field types can be very broad or as specific as needed.

For example, here are a few field types, from broad to specific:

  • Basic text input
  • Basic HTML display
  • HTML editor based on prosemirror
  • Entity field that allows for a list of sub fields
  • List field that allows for editing lists (where each item can again be a list of fields)
  • Tag field that allows for selecting and linking entities in a “tag”-like fashion
  • Image upload and cropping
  • HTML reader which allows for highlighting and storing reading position

On the client side, a field component is just a multimethod that takes a context and the field specification, and then it can use whatever code is necessary to render itself. It could be anything from a simple html display to a complex component calling 3rd party components.

Layout position can also be specified for each field, so you could for example have fields that render in a sidebar or in a menu.

All of that being said, the architecture is optimized for fast iterations, as we have very limited programming resources. UI is pretty basic, but simple and fast.

I’ve been very happy with the speed at which this allows new business features - because all of the infrastructure is orthogonal to the business logic, adding a new business feature /application just requires adding the business logic,all the plumbing has been taken care off.

And improving the infrastructure improves all of the applications - for example recently adding the server side events support is orthogonal to any business logic, but made all of the applications faster and responsive to outside changes. Or, adding a new field type means any future application can use that field type.

re: 1., would that mean payload for each render is the entire HTML document? Concern here is speed & diffing performance. What would be the benefit?

re: 2., yes, the power of native and the reach of web all while avoiding JavaScript.

even on the desktop, people have created architecture that are client/server.

this is order dependent. people have adopted client and server locally because a wealth of tools developed for remote made it desirable. I doubt it was a decision based on first principles.

re: 3.m agree that would be great but also another research project but will require active maintenance. Writing a vDOM is not rocket science. Would love to have one in CLJ and start developing through Jive.

Hum, that’s a good point. I was thinking the benefits would be to offload more compute to the clients, and be able to reuse an existing JS vDOM library.

It’s true that you’d now need to send back the full state. I guess you could send only parts of it, but then to do so you’re just back at diffing on the server.

I’ve seen it adopted out of first principle. I think there’s a few reason for it, most of them are similar to why someone might design a backend as a series of micro-services instead of a monolith.

By creating a hard boundary between server logic and UX/UI logic, it’s really hard to accidentally couple them and end up with a big ball of mud.

As your application grows in complexity, so will the number of developers who have to work on it. By having the code base split up between UX/UI and business logic you can more easily have two teams each dedicated to different parts of the app.

By seperating the UX/UI like that, you can technically support more than one UX/UI framework, so could be easier to have it run on MacOS, Linux and Windows for example, as you could use all their native UI framework and reuse the business logic parts.

It can make it easier to support both a UI/UX as well as a command line and programmatic interface to the application.

And finally. Sometimes even desktop apps are a kind of webapps, where you’ve got an enterprise sever and people’s computer have to interact to it, and they can share all kind of data with one another etc. Even if the UI/UX is not built using html/JS/css.

I’m not saying this is always better, but it make sense sometimes. Jive still sounds great, because right now with the web technologies, you’re forced to use JS and split things this way, so having an alternative would be nice.

I would like to lave a mention for https://htmx.org and GitHub - tatut/ripley: Ring live pages experiment
I’ve been using the first for some internal/personal tooling at work. I had to get a simple app to show some information from the db plus perform some actions like produce docx reports, slack alerts. I don’t know JavaScript and wanted to do something in clojure, plus htmx looked cool:

(defn counter-label
  "Element showing a number. Used e.g. next to nav links"
  ([txt endpoint] (counter-label txt endpoint {}))
  ([txt endpoint extra-attrs]
   (let [base-attrs {:id (str (string/replace endpoint #"/" "") "-counter"),
                     :class "ml-1 text-gray-400 text-sm font-medium",
                     :hx-get endpoint,
                     :hx-swap "outerHTML",
                     :hx-trigger "load delay:14400s"}]
     [:span (conj base-attrs extra-attrs) txt])))

Just wrote Clojure plus htmx as part of the hiccup markup. Works super well for my purposes (those are AJAX requests, but it also supports websockets).
I’ve been watching the development of Ripley for a while but haven’t had time to do something meaningful with it (just noticed you mentioed ripley in your post :slight_smile: )


Thanks for suggesting htmx. Will have a look!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.