Fork me on GitHub
#clojurescript
<
2024-01-07
>
Herman Nurlygayanov18:01:12

I’m choosing what to write a GUI on. Of course, I would like one framework for all platforms (Mac, Win, Linux, iOS, Android). 1. At first, I thought that CLJS + reagent/re-frame would be enough. For desktop through a web browser, for mobiles through ReactNative. But I was concerned by the fact that NuBank dropped ReactNative in favor of Flutter. 2. I searched for alternatives - it seems that only ClojureDart is able to give the necessary access to platforms. But there is a problem with it - it is not mature, there are various bugs. And it is not quite Clojure, you need to port libraries, or launch a proper Clojure back-end. Is there anything else in Clojure world? Does it make sense to rely on the experience of NuBank and mess with Flutter/ClojureDart? What are the chances that in the future ClojureScript will be cured from its JS interop/compilation issues, and CLJS + ReactNative will be smooth to work with?

1
p-himik18:01:08

Feels like the bulk of the question, except for the last part, is more apt for #C03S1KBA2 or maybe even #C03RZGPG3. > What are the chances that in the future ClojureScript will be cured from its JS interop/compilation issues, and CLJS + ReactNative will be smooth to work with? I'm not familiar with RN, but what are the interop/compilation issues that prevent a smooth work with CLJS + RN? Are they about RN specifically or CLJS in general?

ghadi18:01:24

Nubank started using Flutter prior to Clojure/Dart, but if the timing were different we would have definitely wanted to leverage Clojure/Dart

seancorfield18:01:20

@U050ECB92 Do you have any insight into why Nubank switched from RN to Flutter? (or is there a blog post about it?) I ask because we use RN at work (admittedly with a React.js / Redux / Immutable frontend, not cljs) and it has been "good enough" for us so far -- but we're always interested in evaluating better options.

ghadi18:01:44

Besides that article I don’t know much about the rationale @U04V70XH6 .

1
kennytilton18:01:33

My approach, when I see sth cool but new, is to evaluate the team behind it, and especially how quickly and effectively they react to issues. Team CLJD does superwell well on both counts. As for it being "not quite Clojure", true, but it is still a fine Lisp. So I see a glass 95% full, not 5% empty. As for porting things, I guess it depends on what needs porting. I always look for Dart/Flutter libraries when I need more than pure CLJD. If there is a must-have CLJ library, many will port easily. My Matrix library is relatively intense, and used multi-methods for one key mechanism, but I was able to work around that. A final thought is that Flutter is OO, but we get to use it, we do not have to program in OO directly, and CLJD hides a lot of the OO with inferencing. And then we get a massive library of widgets and other functionality. Just my two 🪙 . 🤷

🙏 1
p-himik18:01:41

@UDRFLNJUV There's nothing in that article about compilation and interop. The only downsides to RN that are mentioned are worse hot reloading than with Flutter, a bit worse docs, and an increased maintenance cost due to the high number of RN's dependencies and API instability. So I still have no idea what "cure" you had in mind when writing the OP.

seancorfield18:01:44

Reading the Nubank article, it sounds like they were able to have a mixed RN/Flutter codebase during the migration and having apps with both tech stacks involved (using Flutter for new features... "on existing apps" seems to be implied there)? Am I misreading that or misunderstanding how a migration to Flutter/Dart (or CLJD) might work? I guess that's a Q for @U0PUGPSFR mainly at this point... I suspect @U050ECB92 is more involved with BE/server stuff than mobile?

seancorfield18:01:44

@UDRFLNJUV Can you elaborate on what you see as "its JS interop/compilation issues" wrt CLJS?

Chris McCormick20:01:43

I have built stuff in the browser using CLJS and then ported to native using Cordova/https://capacitorjs.com for mobile platforms and https://www.electronjs.org/ for desktop platforms (Tauri looks good too but I haven't used it). Here's a CLJS app I ported to iOS/Android: https://apps.apple.com/us/app/po-sync/id1664995967 https://play.google.com/store/apps/details?id=cx.mccormick.pocketsync&amp;gl=US Here's a game I ported to desktop: https://chr15m.itch.io/asterogue In my opinion this strategy of building for web first using CLJS and then porting to mobile/desktop using the wrapper frameworks removes a huge amount of the complexity of cross platform ports. As a single developer I don't think I would have the resources to build software for multiple platforms without doing it this way. Highly recommend if you're looking for simplicity.

🙏 1
Chris McCormick20:01:55

I provide this case study because I think it satisfies this requirement: > I thought that CLJS + reagent/re-frame would be enough. I am using Reagent for pretty much all of my apps.

Herman Nurlygayanov22:01:12

@U04V70XH6 @U2FRKM4TW I've read several discussions about CLJS, and what caught my attention is summarized https://tonsky.me/blog/clojurescript-2/: 1. Google Closure uses aggressive optimizations, that often break NPM packages (sometimes in a sneaky way). So in order to be sure that your code will work, you have to disable optimizations, which means bloated bundles/slow performance. 2. "Using Java from Clojure is easier than from Java (not kidding). Whereas in ClojureScript it’s more like: don’t use JS libraries. It’s very hard. There are a million “buts”. Are you in node or a browser?" From personal experience, I worked a little bit with CLJS + ReactNative in 2020, and I felt like tooling was buggy, slow, and immature. If it's true that one has to constantly figure out subtle details, when trying to leverage JS/RN ecosystem in CLJS, then it might be worth investing in ClojureDart or even writing GUI in a different language. In short, I would much prefer to stick with Clojure for GUI, but not sure how much pain it is (and how to avoid it).

seancorfield23:01:19

There were quite a few responses to Nikita's piece, to say the least. thheller had this to say https://www.reddit.com/r/Clojure/comments/14jfs48/comment/jplxjm3/ on r/Clojure and others have also provided arguments against several of the points Nikita was trying to make. My first experiences with cljs were back in 2013/14 and the tooling was def. buggy and fragile and hard to use back then -- and my company decided to go the plain JS route because of our evaluation of cljs (we built a p.o.c. with Om and then rebuilt it with Reagent and weren't happy with the experience either way). ClojureScript and its tooling has come a long way since then -- and a long way since 2020 as well -- so I would rather conduct a new evaluation of my own today than rely on one or two negative blog posts. There are some good posts about "lightweight" approaches to cljs here https://code.thheller.com/ I've always had concerns about the dependency on the Google Closure Compiler (and to a lesser extent the Google Closure Library) but the folks who drive cljs forward are comfortable with it and a lot of production stuff gets built with cljs, including RN apps so... 🤷:skin-tone-2:

🙏 1
kennytilton23:01:27

I think the more interesting question @UDRFLNJUV faces is, at bottom, whether to soldier on with humankind's attempt to teach calypso to our HTML dancing bear, or to embrace Google's insight: start over from scratch and create a tool with full awareness that we have desktop, Web, mobile, and AOT we would like to program. Like, what would Tim Berners-Lee create were he starting today? And would it involve NPM? :rolling_on_the_floor_laughing:

phill00:01:06

> whether to soldier on with humankind's attempt to teach calypso to our HTML dancing bear, or to embrace Google's insight Chasing Google's coat-tails, either way! Google's Closure library and optimizer put CLJS on the map; now Google focuses on Flutter.

💯 1
Chris McCormick10:01:17

> Google Closure uses aggressive optimizations, that often break NPM packages I am writing cljs every day and I have multiple projects with 1000s of daily users in apps compiled with :advanced, including doing weird things like webaudio, and this rarely happens to me. There is sometimes a bit of futzing around to work out the correct way to import a package but beyond that it's usually all gravy, thanks in large part to Thomas Heller's amazing work on shadow-cljs. > ClojureScript it’s more like: don’t use JS libraries. It’s very hard. Again this is not my experience. shadow-cljs is a dream and smooths over many JS warts. I think I have only once or twice run into a package which I couldn't get to work. In those cases I was able to find a suitable alternative. Most packages work the same as in pure JS.

Chris McCormick10:01:28

I should say that I have a fair bit of experience with the JS ecosystem so maybe that's why I am having an easier time and I'm biased in favour of it. My basic summary would be: if you already know JS and its ecosystem then ClojureScript + shadow is absolutely an upgrade to pure JS. If you're writing front end browser code you're going to have to know and understand JS anyway, so there is in my opinion very little downside to using ClojureScript on top.

🙏 1
p-himik10:01:30

> this rarely happens to me If you're using shadow-cljs without specifying :js-provider to :closure, then NPM code doesn't go through :advanced. But I agree with the critique towards Nikita's article - most of the stuff there has little to do with how things actually are nowadays.

👀 1
👍 1
baptiste-from-paris15:01:18

Hello @UDRFLNJUV ClojureDart co-author here 😄 - I am late to the battle but I still think I need to address this block bellow > I searched for alternatives - it seems that only ClojureDart is able to give the necessary access to platforms. But there is a problem with it - it is not mature, there are various bugs. And it is not quite Clojure, you need to port libraries, or launch a proper Clojure back-end. It is not mature, there are various bugs -> I don't agree, we've been producing real world applications for a while now. There are open issues in the cljd repo, same with clojurescript/clojure. We address compiler bugs immediately when we found some. it is not quite Clojure -> you broke my heart, I don't get why but that's your opinion you need to port libraries -> there was a time in the Clojure community where no library existed. Cljd community is growing and more people are porting libs.

🙏 2
2
baptiste-from-paris15:01:45

PS: I am not here to convince you, I just share my opinion 🙏

kennytilton15:01:29

I did not say anything about "there are various bugs" because I was too lazy to check if I had missed issues on the repo. 😳 But, yeah, that one stumped me. I beat on CLJD with esoteric Matrix internals all the time and hit issues maybe once in four months. Once I can repro, they fix in a day. It would be less, but they burn some time deciding which of them is to blame. :rolling_on_the_floor_laughing:

❤️ 1
seancorfield17:01:12

@U0PUGPSFR Not sure if you saw my earlier Q addressed to you in this thread -- about whether a mixed ReactNative/JS + Flutter codebase was possible during a migration from the former to the latter?

kennytilton17:01:57

Yes, @U04V70XH6, but I was not sure what was being asked, and why me! 🙂 My wholly uninformed reaction, and part of the problem, is that I cannot imagine mixing the two, unless by "codebase" we would include what Nubank seems to have done in rolling out different apps per stack. Btw, I use https://github.com/kennytilton/web-mx personally, and re-frame on jobs.

cgrand17:01:40

@U0PUGPSFR > Once I can repro, they fix in a day. It would be less, but they burn some time deciding which of them is to blame. :rolling_on_the_floor_laughing: No way! I took care of streamlining this part of the process from day 1: it’s always @U2N9GDB1U fault!

🧠 1
😄 1
seancorfield17:01:12

Thanks, @U3E46Q1DG! Interesting. I've gone through a lot of rewrites over my career and always like to see an incremental option 🙂

seancorfield17:01:57

@U0PUGPSFR I @-d you because you were/are the "resident Flutter expert" in the thread at that point 🙂

👍 1