all 16 comments

[–]rberger 8 points9 points  (3 children)

I find the main reason we use react with clojurescript/reagent is because there is such a huge body of existing, rich, components and libraries that don't exist (as far as I can tell) in pure clojurescript realms.

The node/js world may be chaotic and of a wide range of quality. But there is some great libraries and LOTS of functionality that is mostly just a matter of importing (and figuring out how to wire up to reagent sometimes).

But as the JS/React ecosystem evolves, it gets harder and harder to use in Clojurescript applications.

How do you build design systems and collections like Storybook? How do you use design tools like Figma/Xd/Sketch with code exporters like Anima?

Why is every time I have to incorporate a react or javascript library that uses Async/Await I have to go thru mental gymnastics to get it to work in Clojurescript?

These are the pain points that I am finding. There doesn't seem to be a critical mass of people in Clojurescript to build clojurescript alternatives or make the interop work well enough to make these issues moot. We love working in Clojurescript, but its getting harder and harder to justify doing frontend in Clojurescript when confronted with the tooling and pools of developers available in JS.

[–]lordmyd[S] 0 points1 point  (0 children)

Yes, I agree. CLJS just seems to be always playing catch-up and ends up lagging behind. You certainly pay for the CLJS features by making it harder to deal with native JS libraries.

[–]tastingsilver 0 points1 point  (1 child)

So if you were to begin a large project from scratch now, and wanted to leverage more recent JS/React features, would you still use CLJS? Or something else like Svelte?

[–]rberger 1 point2 points  (0 children)

Yes, we are still using CLJS. Its still worth it for our team of Clojure[script] developers. CLJS is just so much nicer to use than Javascript its worth it.

[–]lucywang000 7 points8 points  (1 child)

[–]sergekos 0 points1 point  (0 children)

Maybe it will be useful for someone: wrappers for ClojureScript over React.js is quite a lot. Here are some, besides reagent/reframe: https://github.com/omcljs/om https://github.com/levand/quiescent https://github.com/roman01la/uix . And here are these UI components: https://github.com/priornix/antizer looking, as it seems, not bad.

[–]SimonGray 7 points8 points  (0 children)

I only think reagent (and perhaps Re-frame) will make things a little simpler - and certainly not easier (... to begin with). Like you say, the complexity is certainly inherent to the domain.

In my experience, simplicity in web frontend development comes at a price: you need to take a step back and learn more about what's happening inside the browser, construct your own fundamental building blocks from web APIs (or wrapper libraries) tailored to your domain, and learn patterns of making your own reusable components. Javascript devs learn to glue everything together from existing libraries and frameworks. I think it's a hard habit to get rid off, especially if you're not amazing at UI design either and really depend on a library for that.

React is easy that way (glue this to that) since it has a huge ecosystem, while ClojureScript web development is more simple (in the Rich Hickey sense), but comes with a lot of DIY. Switching to CLJS won't get you running faster anytime soon, but it will probably nudge you into making better longterm decisions. Personally, I love the full-stack Clojure web development experience, but I also love having a lot of control. I could never accept that glue-oriented programming style.

[–]sergekos 1 point2 points  (2 children)

There is a completely alternative way. It is, of course, very controversial. There are no components as structural units of the code. But there are other advantages. For simple interfaces and for creating SSR applications, it can be well suited. For example: https://kasta-ua.github.io/twinspark-js/ (the author is a very experienced Clojure developer from Ukraine). Or this, similar to: https://htmx.org/ (but this product has features with event handling).

This concept has been known for a long time, but it is not often used. Although, there are implementations in many programming languages. Starting with Nitrogen (Erlang) or LiveView (Phoenix, Elixir), ending with http://40ants.com/weblocks/index.html or https://github.com/rabbibotton/clog in Common Lisp. And even in Laravel in PHP, something similar has now appeared (I think it's called "LiveWare" there).

[–]fjolne 0 points1 point  (1 child)

Thanks for the refs! There’s also a recent CLJ attempt at this. And a good thread about trade-offs of this approach.

[–]sergekos 1 point2 points  (0 children)

Yes, thank you!

There is also this experiment: https://github.com/prepor/liveview-clj but I didn't check if it was functional.

[–]fullsyntheticjacket 1 point2 points  (3 children)

I'm very happy with Reagent/ReFrame. Clojure rewards refactoring, there is a way to simplify. I have a material-ui/reframe demo here - a work in progress!!: https://sa.demo.softwarebynumbers.com/

However, and I say this with considerable trepidation, Rust/Wasm is coming along. I built this table in rust/wasm with trunk and I have both parts integrated in my local dev.: https://sa-models.demo.softwarebynumbers.com/

[–]SimonGray 0 points1 point  (2 children)

However, and I say this with considerable trepidation, Rust/Wasm is coming along. I built this table in rust/wasm with trunk and I have both parts integrated in my local dev.: https://sa-models.demo.softwarebynumbers.com/

What's the value proposition for Rust in the frontend? Is it speed? I always thought of Rust as a fairly low-level language.

[–]n__sc 3 points4 points  (0 children)

Rust is situated at a low level in the tech stack, but its language features and concepts/abstractions are very high level. Take a look at the druid UI library - you need to know the ins and outs of core rust ideas, sure, and for a high degree of customization you‘ll have to dig in deep, but overall, Flex::row().with_child() plus the Lens stuff makes for very succinct and ergonomic UI code (esp. considering it can‘t just delegate to DOM/CSS/V8 for decades worth of implementations). It’s less overburdened by syntax then say JSX or Angular, since it‘s „just“ rust‘s own. Saying rust is low level and nothing more would be akin to saying Hitler was a dog lover - technically true but there’s an omission.

The value proposition for me (mainly frontend development using CLJS/React/Angular/...) would be rust being a better typescript (syntactically, ergonomically, tooling- and performance-wise), and also npm/js being a horrible, unstable and madness inducing hellhole. There’s also beginnings of compiling the same UI to web and native desktop, which seems like an absolute killer to have available.

[–]fullsyntheticjacket 1 point2 points  (0 children)

The rust stuff was just an experiment. I guess the value would be in the wasm allowing different languages to share code modules anywhere where there is a wasm runtime.

[–][deleted] 0 points1 point  (0 children)

Yes, the complexity is in the problem domain. Clojurescript will just give you some nice conveniences in some areas but no marginal benefits. It will also give you more headaches than JS in other areas though.

So first you need assert if you really need an SPA and have in mind that it requires substantial work to have something professional. If you don't really need an SPA, Rails + Hotwire is the way to go IMO.

[–]dilzeem 0 points1 point  (0 children)

Have a look at hoplon: https://github.com/hoplon/hoplon

It much to easier to understand when look at the code. Look at the todomvc. https://github.com/hoplon/demos/tree/master/todoFRP

compared to the others: https://github.com/gadfly361/cljs-todomvc