Clojure: Realtime collaborative web apps without ClojureScript

bko | 172 points

One thing I've always liked about the Clojure community, is that they are obessesed with state. I think they have correctly identified, that when things go sideways, it is because state management was involved in some way. This is a cool front end approach using datastar to put all of the state on the backend and side step front end state management entirely. There are some other really interesting things happening with electric clojure and a new "framework" called Replicant. Of all of them, Replicant seems the most intriguing to me personally. If it didn't exist, I think I would be trying to use datastar as this article outlines.

nkh | 7 days ago

There are two main high-level approaches for architecting web application client state:

1. Client-heavy state management (separate client application)

2. Client-light state management (thin client)

The state has to be tracked and managed somewhere. In most web applications, that state is persistable - at some point, it will end up in a DB of some kind.

As such, we already have to handle it on the server side, regardless of whether we also choose to separately manage it on the client side or not.

So the question at the end of the day is: Do I want to separately manage the application state on the client side, when I am already managing it on the server side?

In a lot of situations, the pragmatic answer would be "No". Why? Because managing the state in two places causes duplication, synchronisation issues, diverging logic issues, and so on. We are increasing the accidental complexity of our solution. Maintainability becomes slower, riskier and more expensive.

For some applications, the extra complexity might be worth it. In most web applications I have worked with (eCommerce, internal business tools, booking systems, online calculators, business dashboards), it is not.

And "let's keep all state and processing on the server" does not anymore mean no real-time or highly interactive features. With SSE and fast HTML fragment merging, we can enjoy highly interactive and performant web applications with almost no client-side application state management.

andriusbartulis | 7 days ago

The linked post relies on the Datastar project, which requires use of `unsafe-eval` in one’s Content-Security-Policy [1]:

> When using a Content Security Policy (CSP), unsafe-eval must be allowed for scripts, since Datastar evaluates expressions using an IIFE (Immediately Invoked Function Expression).

The project itself links to Mozilla’s docs on CSP, which state:

> The unsafe-eval keyword can be used to override this behavior, and as with unsafe-inline, and for the same reasons: developers should avoid unsafe-eval.

Out of the box, htmx uses a similar approach, but one can disable this use of eval [2]:

  htmx.config.allowEval - can be set to false to disable all features of htmx that rely on eval:
  
  - event filters
  - hx-on: attributes
  - hx-vals with the js: prefix
  - hx-headers with the js: prefix
[1]: https://github.com/starfederation/datastar/blob/develop/site...

[2]: https://htmx.org/docs/#configuration-options

j13n | 7 days ago

Author of the blog post here. Happy to answer any question!

andersmurphy | 7 days ago

Oh and something I forgot to mention in the blog post.

- The server is in Europe. - The process can be modified at the REPL while It's running (and the changes get pushed out to all users by the SSE). So the board, HTML, CSS etc can all be changed on the fly without a restart.

andersmurphy | 7 days ago

My summary: one single copy of state is maintained on server side and clients are updated through polling or SSE.

pm2222 | 7 days ago

BTW the demo app is broken: white screen with some Content-Security-Policy errors in the console.

mike_ivanov | 7 days ago

To clarify, dealing with spotty connection / offline mode is not possible with this kind of approach?

sooheon | 7 days ago

But.. SSE is limited to like 6 or so connections per browser, no?

mike_ivanov | 7 days ago

That's cool, but as a developer building web apps, I'm not competing with php websites, I'm competing with native apps.

lerp-io | 6 days ago

[dead]

oldpersonintx | 7 days ago