New to Clojure, need advise on using it in a JS frontend project

Hello Clojurians,

Brief introduction:

I am Ravi, primarily a backend engineer from the Java/JVM verse. Primary language is Java and have dabbled in other JVM languages like Groovy, Kotlin, Scala. New to Clojure, like brand spanking new, like ran into it this week new. And so far, I love it, even though the syntax made my head hurt for first few hours :slight_smile: and still does from time to time :D. I have spent some time (like say 10-20 hours) going over Richard Hick’s videos, tutorial, Clojure for the Brave and True book. I primarily got interested because I am working on NodeJS / Javascript / Typescript project(s) and sometimes I can’t find my own code readable. Clojure though on the other hand, looks simpler.

Here’s my very nooby questions (so please be gentle):

a. I have a pet front-end project (JS, TypeScript, NodeJS, Firebase, Quasar/Vue). I am thinking about starting to write new code in Clojure JS, and so to integrate it I started with https://github.com/thheller/shadow-cljs. I followed the instructions there but found the JS file spit by the project to be huge just with a hello world function in it. I was expecting it to be a simple small JS file. I have read that that’s because CLJS (100K + line of code is) is packed in? If we are compiling to JS, then why do we need CLJS?

b. Would you advise writing some (helper) functions in ClosureJS and using it in JS? I am afraid the size of the JS file will be too big and it might not be advisable/smart to intermix JS code and CLJS code vs writing everything in CLJS and compiling to JS.

c. I am using Quasar (https://quasar.dev/) and love it. Are there similar frameworks in Clojure JS? I came across Reagent / Reframe but not sure if they have already provided components that look as beautiful / well laid out. I am a newbie to the front end so I don’t have mad CSS skills like other folks to beautify Reframe/Reagent.

d. I understand there are lot of benefits from functional paradigm and immutability etc. But purely from a performance point of view, does CLJS end up being slower / equal / faster than vanilla JS?

e. I am reading Clojure for the Brave and True book and find it to be excellent. Any other resources you would like to share to learn Clojure. Should I learn Clojure first and then ClojureJS?

I understand these are a lot of questions. So I don’t mind asking them individually via individual posts.

Thank you in advance for your time and effort in helping me.

Regards,
Ravi Hasija

1 Like

I just finished doing this same thing, a front-end only CLJS app with Shadow, and will finish my detailed article about the process soon. Your post motivates me to get this done this weekend.

2 Likes

Welcome! I still have much to learn when it comes to Clojurescript myself, but here’s what I can tell you about the questions you asked:

a. How big is your final .js file? The compiled size depends greatly on the advanced optimizations done by the Google Closure compiler. Hello World should be around 90KiB when optimized. As to what exactly it contains I cannot say, but it should be the secret sauce that gives you Clojure semantics in a JS runtime, so e.g. JS implementations of Clojure’s immutable data structures are a part of it that cannot be compiled away.

b. I’ve never done that and cannot even see a reason why I would try as far as simple helper functions are concerned. In case of a massive function taking care of a significant part of your business logic you might try to set up CLJS to produce a JS library that you should be able to call like any other. Shadow-cljs only has built-in support for a :node-library target, which suggests that this would be a rather unlikely scenario on the frontend. In any case you probably don’t want more than one of these because (I think) you’d be duplicating the CLJS code common to all of them (see a.).

c. I dont’t know Quasar so maybe someone else can chime in here. Just one thing: You can actually use existing React components with Reagent. If there’s anything like Quasar for React it should be usable.

d. Overall the performance of Clojurescript is surprisingly good. Reagent even tends to be faster than vanilla React, courtesy of Clojurescript’s immutable data structures, which facilitate diffing the virtual DOM with the actual DOM.

e. There’s many resources… Definitely put some work in
4clojure.com. As far as books go I really appreciated Clojure Applied (more advanced than “Clojure for the Brave and True”). For web development take a look at the current beta of Sotnikov’s book. The one book I aquired specifically for Clojurescript was disappointing, so I’d rather recommend this tutorial.

Maybe some of this helps. If I’m wrong on anything I hope some of the more seasoned Clojurians around here will correct whatever is off.

Cheers!

2 Likes

Normally people come from JavaScript would think ClojureScript like another CoffeeScript, another PureScript, another TypeScript, another ReScript or BuckScript, that compiles to JavaScript, vanilla JavaScript. But NO! ClojureScript is different. ClojureScript is built at its core with persistent data structure, which basically another library on top of JavaScript(mori) and it could hardly generate same JavaScript code like from CoffeeScript or TypeScript. Meanwhile ClojureScript tries to keep aligned with Clojure in macros, samentics… and that also add to the difficulties making ClojureScript a Clojure -> js transpiler.

So ClojureScript is more like a language on top of JavaScript, rather than another CoffeeScript/TypeScript. Just keep that in mind.

4 Likes

There we are. Creating ToryAnderson.com with ShadowCLJS | Tech.ToryAnderson.com

1 Like

Thank you guys so much! I have come to the understanding that writing some small business functionality in Clojurescript might not be worth it’s while to include in JS project.

I really would like to build a new app in Clojurescript, but (correct me where I am wrong) it seems like there’s no write once deploy everywhere solution that works easily for a novice like me. Here’s what I mean by that:

I am a newbie to JS but there are frameworks like Quasar that make it super easy to create a well designed / good looking SPA, PWA, with easy build and deploy for IOS / Android via Cordova / Capacitor. Basically, a built in solution for inexperienced JS developers to build and deploy good looking websites / webapps / pwas easily.

My plan is to finish my current learning app: a Todo app and then try to build and deploy the same app via CLJS as SPA/PWA and deploy to app stores via Cordova/Capacitor. This way I can build a non-trivial app in CLJS and learn about the process in depth.

Thank you all for your time! And please feel free to add your thoughts to this thread … I welcome your thoughts on my conclusion so far.

1 Like

The target audience for Clojure and ClojureScript are generally more experienced developers looking for something that offers them more power and flexibility while having saner safer default behavior and with a more interactive and productive development workflow.

It doesn’t mean there couldn’t have something made for beginners, but there’s not as much focus on that, so I can’t really think of anything of that sort.

That work easily for a novice I’d say no. Now I’ve never used Quasar or other such “for novice” frameworks, and I suspect it isn’t anymore “easy” then what you’d do in Clojure/Script, but will likely have so much more tutorial and documentation and guides and support that it’ll probably be easier for a novice for sure. But I also suspect most such frameworks in Clojure are going to be somewhat proprietary or of open-sourced, probably have no other users but the company that runs it, so again, no documentation and all that.

2 Likes

One thing that I’m still experiencing with is to create components in clojurescript that can be used in any front end project. I suggest taking a look at this thread by Thomas Heller Generating ES Modules (Browser, Deno, ...)

1 Like

The write-once/deploy-everywhere for Clojure is the JVM (okay – arguments are noted; but that’s the idea, anyway). For ClojureScript it’s the fact that you are literally deploying to html & javascript, literally as “everywhere” as you can get. Maybe I’m missing your meaning?

Now, easy to make a decent looking thing – exactly what @didibus said. Clojure is typically aimed at more experienced devs who are expected to already want to take care of such things. The huge benefit to this is that you will learn to become one of those advanced devs by working through it Clojure-style. In the meanwhile mini-frameworks like Luminus offer a lot of sensible suggestions to get you started on this path, making advice of some of the CSS frameworks and CLJ[S] libraries that can get you started.

It’s not a very warm-and-fuzzy answer, but I can tell you I’d much rather work in 6 months with someone who has gone through the Clojure process than someone who step-stooled on a framework to achieve something pretty they only partially understand. (This is a controversial topic, though)

2 Likes

Right. I completely agree with all of what you have said!

So this might not be a good time for me to jump with both feet in CLJS. With Clojure aiming at JVM world, that seems a more likely fit as I have decent amount of experience in backend as compared to a novice/beginner level in frontend. But, I was looking for another tool language to take the pain of JS away.

I will look at Luminus, but I am in agreement with @didibus and you that CLJS is for advanced web-devs who can roll up their sleeves and make things look pretty via hand coded css. Clojure/CLJS is a beautiful language; the only thing missing IMO (maybe intentionally) is making it easier for newbies to make it pretty via a CSS/UI framework.

1 Like

The other thing I should add is that many of the things intended to give people a quick-start in Javascript or HTML will work just fine with your app; you can use Selmer for templating some framework HTML, you can use Bootstrap or Bulma for standard styling stuff, or any of the 1000s of other javascript/web solutions out there. You can pick a web page you like and just plop the code into your app and start adding little things. So Clojure will never make those decisions for you, but it allows you to make virtually any decision you want. The glory of being a hosted language.

Also, check this beautiful little example out: Small web apps with Babashka: Luminus guestbook-reagent example

Oh, that’s interesting. Would you be able to point me to a blog post / example website that does it. I will try and look for it too! I think that’s the next step up! I have a play TODO fully JS/Firebase app, that I can try converting to CLJS.

I was introduced to Bulma through Luminus (which used Bootstrap in earlier versions). At this point you leave CLJS-specific land because you’re talking about CSS and Website frameworks so anything works from the web. You don’t need Clojure-specific stuff.

Here are Bulma example sites: https://bulma.io/expo/

To see some some cool stuff involving clj and Firebase-related work, check out https://github.com/jacobobryant/biff and contact Jacob O’Bryant directly (he’s active in most of the major social places including Twitter and Clojurians Slack, too).

Any cool examples with code that you find on the web in CSS, HTML, and Javascript should be easily convertible to Clojure[script].