I am starting to experiment with weaving in #replicant into my Biff app. Per an an https://clojurians.slack.com/archives/C013Y4VG20J/p1738686114688679, there is probably a lot of overlap of functionality in terms of a full-stack approach. And Jacob has suggested before that if one wants full cljs, maybe the Biff setup is not adding much value (and it would be simpler just to go full Replicant, , which in context has a scope similar to Reagent + Re-Frame). But I have heard noises of people using Replicant in conjunction with HTMX (since Replicant is just updating dom nodes, which can still have HTMX properties) and/or also using Replicant server side to compose HTMX infused chunks of HTML. So far I have a working demo of Replicant reactive state working on a dedicated route on my Biff app, and shadow-cljs does watch and re-build on that page. I have also looked at the https://biffweb.com/p/how-to-use-reframe-with-biff/ tutorial for guidance. I’m not sure exactly what I want. I like simple generated html pages that have classic routing, like Biff provides. But I want to lean towards full control and ability to reason about advanced interactivity on the client site. The notion of stacking up “extra” discrete languages give me pause (html + htmx + css + tailwind + hyperscript + js + alpine.js + etc). Even though I probably would not need those all at once, and semantics of each are simple, the challenge of intuitively knowing the rules and limitations of x different syntaxes at once seems significant. PS. Maybe DataStar bundles that declarative hypermedia stack up sufficiently? I think one of the ideas of Replicant over HTMX is that it is a simple but sharp tool that can scale from simple (jquery-like) to very complex solutions in a consistent (data-driven) working style. For me this may be worth the price of extra cljs dev complexity and larger bundle size. I’ve always been attracted to the cljs proposition of 1 language for client & server (even if that hasn’t historically paid the most dividends) Thoughts anyone? @rads What was your experience with your Rain framework (next.js style) https://github.com/rads/rain. I believe that started as an extension of Biff? It seems like Replicant would be especially good at hydrating static pages for SSR approaches..?
Sounds worth exploring for sure! Definitely interested in hearing how this goes for you.
> @rads What was your experience with your Rain framework (next.js style) > https://github.com/rads/rain. I believe that started as an extension of Biff? > It seems like Replicant would be especially good at hydrating static pages for SSR approaches..? I've been typing up a bunch of different replies to this and I guess my answer is: hybrid rendering (e.g. hydration, React Server Components) is quite complex and probably not worth it unless you already know the tradeoffs well. Replicant would work fine if you do go down that route, but you would also lose compatibility with existing React libraries
Perhaps Vercel will eventually come up with the perfect hybrid rendering framework with enough time and funding, and then we can copy it in Clojure. Unfortunately Rain's hydration approach (page-based) was already out-of-date by the time it was released and React Server Components are the new frontier
Interesting. I’ve seen React Server Components scoffed at on the Electric thread (…like its striving towards necessary client/server blending, but hopelessly limited..). But Electric is very SPA oriented and seems far from the low-bundle easy to serve brochure pages Biff can provide. Your right that Replicant eschews the whole React ecosystem in favor of it’s own DIY ethic. I’ll just have to dig in and feel out the tradeffs better. Will report back.
Yeah, I think that's a big downside of the RSC and/or Electric approach: you get to blend client/server code, but you have a lot of abstraction going on to make that work For my latest project, I've been using a technique I think is a good balance: the app is fundamentally a server-rendered app with no client-side routing, but I define https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements when I need to use CLJS. This is a different mindset: instead of hiding the division between the client/server, we think of them explicitly and treat them as two different stages of rendering In some circles https://www.patterns.dev/vanilla/islands-architecture/, but the important thing is that you can make your islands as big or small as you want. So if you have a whole page that's better suited to CLJS, you can return a custom element from the server that renders a whole page. If you just need it for a small piece of your site, you can have a smaller custom element that does that and leave the rest of the rendering as server-based Hiccup
The islands approach would work well with Biff if you don't want to use HTMX since all the server is doing is rendering Hiccup with your custom elements. Since custom elements are a standard browser API, you can use whatever you want to render the element when it starts up (e.g. Replicant or Preact)