Isomorphic ClojureScript

602 views
Skip to first unread message

Marc Fawzi

unread,
May 19, 2015, 1:17:10 PM5/19/15
to clojur...@googlegroups.com
Is anyone out there working on a pattern of framework for isomorphic ClojureScript?

My sense so far is that most are happy running Clojure on back end and ClojureScript on front end. But Matt's recent post made me think of Isomorphic apps. For example, you can have the 1st page render server side so it's pre-rendered for faster load, and then have the rest of the app (all other pages) run in the client.

Meteor just got $20M to build the isomorphic js framework to rule them all.

Any interest in this within the ClojureScript community?

Sent from my iPhone

Daniel Kersten

unread,
May 19, 2015, 2:42:27 PM5/19/15
to clojur...@googlegroups.com
I looked at DomKM's server-side Om some months back, but that's about it.

I'm not really interested in running a ClojureScript server (Clojure is much better suited for that), but performing 1st page render is something I'm interested in (perhaps through an approach similar to DomKM's - ie running cljs in nashorn or similar). I don't have a big need for it right now though, so I'm not likely to put any effort into it myself any time soon.

I am interested in seeing what others accomplish, though.

--
Note that posts from new members are moderated - please be patient with your first post.
---
You received this message because you are subscribed to the Google Groups "ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojurescrip...@googlegroups.com.
To post to this group, send email to clojur...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Marc Fawzi

unread,
May 19, 2015, 3:26:15 PM5/19/15
to clojur...@googlegroups.com
ok, thanks for reminding us about Dom's work. I'll ping him and see if he's done any further thinking on this. 

I tweeted about it to ask the community for input and Jim Laskey the Nashorn dev lead picked up the tweet and RT'd so I can only assume that the Nashorn community would interested in any efforts toward Isomorphic ClojureScript leveraging Nashorn. 


Matthew Phillips

unread,
May 19, 2015, 5:06:30 PM5/19/15
to clojur...@googlegroups.com
I think running ClojureScript server-side in Node is the future. Server-side rendering has an advantage not just in SEO but in user-experience as well.  I don't know if that's ever something Clojure-JVM is going to be able to do.

Marc Fawzi

unread,
May 19, 2015, 5:23:55 PM5/19/15
to clojur...@googlegroups.com
I think we (as an industry) ended up with SPAs because we embraced HTTP APIs and if you have an HTTP API then you have two logical outcomes:

1. Render pages server side with some performant data layer, sidestepping the HTTP API and it's associated overhead but incurring the cost of server side rendering <--- this means that you don't get to consume your own API which is not an issue if you have full test coverage but it could be an issue in that you won't experience the pain that your API customers experience and won't have the same feedback to help you evolve and improve your API, i.e no internal customers

2. Render pages client side and use the HTTP API, which definitely has an associated overhead but you compensate for that by shifting the rendering job to the client

What doesn't make too much sense to me is rendering server side while going thru an HTTP API .You incur the cost of both the server-side rendering and the HTTP API. Having said that, in this scenario, if you only server-side-render the initial page then it still makes sense.

The above conclusion is debate-able of course, but I'm not sure what I'm missing here.



Matt Ho

unread,
May 19, 2015, 5:48:17 PM5/19/15
to clojur...@googlegroups.com
I briefly tried Clojure on the server side, but I ended up deciding that Node, despite its immaturity was more comfortable for me. In general, my problems were:

Developed felt sluggish:

* Very long boot time - cold boot, including cljs compile but not downloads, compile is over 1min compared to 10sec for similar node boot
* Slow REPL cycle (5sec+ per reload) - Using optimization: whitespace. I wasn't able to figure out how to make it work with optimization: none. Compare this to a nearly instant reload time in node

Having both Clojure and ClojureScript was confusing:

* I'm not very familiar with Clojure and having learn its idioms and libraries of ClojureScript seemed prohibitive. Node is new as well, but given that it's JavaScript, it was more comfortable.

So for others, I can see Nashorn would be a good choice, but I think for me and I might guess others coming from the JavaScript world, Node probably makes more sense.

Matt Ho

unread,
May 19, 2015, 6:00:45 PM5/19/15
to clojur...@googlegroups.com
Let me give a slightly different take on it. My sense is we got to SPAs because the industry wanted more responsive and more dynamic web sites. That said, I would break down sites into one of two types; those that need/want SEO and those that don't.

For non-SEO sites (anything password protected), the initial page render is nice, but not absolutely required. Some very high traffic sites, like Facebook and Gmail, continue to do mostly client side rendering. Administrative sites like the AWS console also nicely fit into this category.

For the SEO sites, server side rendering is a business need. I'm trying to think of a case where a major site that tried client-side rendering only didn't eventually come back to server side rendering (at least for the first page). Some notable examples would be Twitter and Airbnb. They tried, client-side only, but ended up rendering the first page server side.

Ok, last point and I'll stop ranting ;) As for the additional HTTP request, my sense is that it's not the number of requests, but the overall latency (or time to first Tweet as Twitter would put it) that's important. Most modern sites (Google, LinkedIn, Facebook, Netflix, etc) use many services to handle a single request. What's important is that these low-latency requests don't significantly impact and may even reduce overall latency.

Daniel Compton

unread,
May 19, 2015, 8:13:26 PM5/19/15
to clojur...@googlegroups.com
I'm definitely interested in this. My use case is an app which makes a number of cacheable HTTP requests for individual resources which is kept up to date over time. Having the server returning a rendered page and letting the client make requests to update the resources later would cut down on load time hugely.

Zubair Quraishi

unread,
May 20, 2015, 7:22:43 AM5/20/15
to clojur...@googlegroups.com
This is incorrect, Meteor got 20 million to build a "full stack" and "real time" framework. That is what the investors are eyeing. The fact that it is Javascript on the front end is important, but not the backend

Zubair Quraishi

unread,
May 20, 2015, 7:45:48 AM5/20/15
to clojur...@googlegroups.com
On Tuesday, May 19, 2015 at 7:17:10 PM UTC+2, marc fawzi wrote:
And yes, I am working on a similar one for Clojure.... still in progress but will be Clojure on server and Clojurescript on frontend and have real time support for databases (the old version is up on github, but new one going up soon):

https://github.com/zubairq/coils

Matthew Phillips

unread,
May 20, 2015, 8:42:17 AM5/20/15
to clojur...@googlegroups.com
Yes, if I wasn't clear, when I say "server side rendering" I do mean server side rendering of SPA (Om, Reagent) applications.  If we're just talking about old-school server-rendered sites I would agree Clojure would be the way to go.
 
The interesting thing about using ClojureScript is that you can toggle between a SPA and a completely server-rendered site very easily.  All you have to do is not include the <script>s in your response and you have exactly that.  But with the same code-base.  Very cool concept imo.

Marc Fawzi

unread,
May 20, 2015, 9:33:55 AM5/20/15
to clojur...@googlegroups.com

Isomorphic here is far more important to those choosing Meteor than the fullstack aspect alone, especially given that we have been (for many years) building fullstack JS apps with NodeJS as the API integration platform and SPAs in client but as everyone knows full stack is not the same as isomorphic. In the last couple of years I've been hearing some real enthusiasm about isomorphic JS but never really understood the motivations behind it. Meteor (if you've been to any of the meetups) prides themselves on being the leading isomorphic JS framework. Don't mind what the VC pitch deck says, they are the leading isomorphic platform:



Jamie Orchard-Hays

unread,
May 20, 2015, 9:56:03 AM5/20/15
to clojur...@googlegroups.com
Didn't read like a rant, but rather as some well thought-out points. :)

Khalid Jebbari

unread,
May 20, 2015, 9:56:16 AM5/20/15
to clojur...@googlegroups.com
Javascript developer speaking. The problem with isomorphic apps the Node.js way (not the Meteor way) is that you want to run the SAME code both sides, and client-side concerns aren't server-side concerns. Given it's the same language, and some thing are side-agnostic, indeed a great amount of code is shareable like templates (and event handling with React.js), which make the 1st render fast. But other concerns can't really be written the same way on both sides.

Current solutions :
- Use CLJX/CLJC to split what goes to the JVM and what goes to the browser from the same source. Nice, and you get Clojure everywhere
- Use JS/Node.js, and use a build tool like Browserify/Webpack that allow you to replace 1-to-1 some files for server-side and client-side. So you need to write your own common interfaces, not easily done.
- Use Meteor, and have simple "if(isClient/isServer)" in your code to split the concerns and let Meteor deal with rest. The thing is that Meteor is not really compatible with the rest of Node.js/npm ecosystem, and they make lot of choices for you about the stack.

Something lacking with CLJX/CLJC AFAIK is that you can't target *both* Node.js and the browser from the same Clojure code base.

David Nolen

unread,
May 20, 2015, 10:00:17 AM5/20/15
to clojur...@googlegroups.com
On Wed, May 20, 2015 at 9:56 AM, Khalid Jebbari <khalid....@gmail.com> wrote:

Something lacking with CLJX/CLJC AFAIK is that you can't target *both* Node.js and the browser from the same Clojure code base.

Not entirely true. The the cljs.core/*target* dynamic var will be bound to the string of the target, currently "default" and "nodejs" are the only possible values. You can write ifs/switches on the value of this dynamic var. cljs.core/*target* is actually a Google Closure Compiler define so in advanced mode any code in a target block that doesn't match will get eliminated.

David 

Marc Fawzi

unread,
May 20, 2015, 10:02:37 AM5/20/15
to clojur...@googlegroups.com
<< Use CLJX/CLJC to split what goes to the JVM and what goes to the browser from the same source. Nice, and you get Clojure everywhere>>

I love this idea in principle but seeing how confusing reader conditionals can be to a beginner I would personally stick with the Om/Reagent isomorphic path (nashorn or node) ....


Khalid Jebbari

unread,
May 20, 2015, 10:11:28 AM5/20/15
to clojur...@googlegroups.com
@David, I didn't know this feature. Good to know !

@Marc : it's a matter of trade-offs. Node.js and the JVM are very different platforms. If developer convenience is very important, isomorphic the node.js way with Nashorn or Node could be a good thing. Depends on the developers :)

Khalid aka DjebbZ
@Dj3bbZ

You received this message because you are subscribed to a topic in the Google Groups "ClojureScript" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojurescript/T6no_srtBzc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojurescrip...@googlegroups.com.

Marc Fawzi

unread,
May 20, 2015, 10:26:41 AM5/20/15
to clojur...@googlegroups.com
@khalid true re: trade offs... also, good to diversify.... thinking in just one tech all day can be a path to ideological stuckness ... :)

Khalid Jebbari

unread,
May 20, 2015, 10:29:04 AM5/20/15
to clojur...@googlegroups.com
That's right ! Ideology leads nowhere. And we'll all have to write javascript (for browsers) one way or the other anyway :)

Dustin Getz

unread,
May 20, 2015, 12:59:09 PM5/20/15
to clojur...@googlegroups.com
> Is anyone out there working on a pattern of framework for isomorphic ClojureScript?

Yes, I am, it's basically a shell Clojure/Pedestal app that calls into a specific ClojureScript interface where the entire application is defined as a single page app, it prefetches the initial ajax payloads, supports URL redirects and can heal incorrect URLs to the canonical URL, works with <head> content, supports 404s etc. It's very very fast! Sooner or later I will write a blog post. It's not a lot of code though it did take some amount of thought.

Daniel Kersten

unread,
May 20, 2015, 1:03:20 PM5/20/15
to clojur...@googlegroups.com

Sounds great. Definitely looking forward to blog post when you get to it!


On Wed, 20 May 2015 17:59 Dustin Getz <dusti...@gmail.com> wrote:
> Is anyone out there working on a pattern of framework for isomorphic ClojureScript?

Yes, I am, it's basically a shell Clojure/Pedestal app that calls into a specific ClojureScript interface where the entire application is defined as a single page app, it prefetches the initial ajax payloads, supports URL redirects and can heal incorrect URLs to the canonical URL, works with <head> content, supports 404s etc. It's very very fast! Sooner or later I will write a blog post. It's not a lot of code though it did take some amount of thought.

Marc Fawzi

unread,
May 20, 2015, 1:05:49 PM5/20/15
to clojur...@googlegroups.com
Hey Dustin,

That's awesome. I had used some of your stuff before so familiar with the quality of your work!

What's the github url? :)

On Wed, May 20, 2015 at 9:59 AM, Dustin Getz <dusti...@gmail.com> wrote:
> Is anyone out there working on a pattern of framework for isomorphic ClojureScript?

Yes, I am, it's basically a shell Clojure/Pedestal app that calls into a specific ClojureScript interface where the entire application is defined as a single page app, it prefetches the initial ajax payloads, supports URL redirects and can heal incorrect URLs to the canonical URL, works with <head> content, supports 404s etc. It's very very fast! Sooner or later I will write a blog post. It's not a lot of code though it did take some amount of thought.

Dustin Getz

unread,
May 20, 2015, 2:44:28 PM5/20/15
to clojur...@googlegroups.com
Marc, Unfortunately I wrote this for a client so it's not open source yet. I'll post here when I get around to it.

Marc Fawzi

unread,
May 20, 2015, 2:51:52 PM5/20/15
to clojur...@googlegroups.com
Ok, please do! Thank you.

On Wed, May 20, 2015 at 11:44 AM, Dustin Getz <dusti...@gmail.com> wrote:
Marc, Unfortunately I wrote this for a client so it's not open source yet. I'll post here when I get around to it.

--

Matthew Phillips

unread,
May 20, 2015, 3:55:03 PM5/20/15
to clojur...@googlegroups.com
So are you spinning up a Nashorn instance?

Dustin Getz

unread,
May 20, 2015, 4:15:29 PM5/20/15
to clojur...@googlegroups.com
Yes, 99% of the application logic is defined in clojurescript e.g. Routing and Ajax queries, there is a very small amount of JVM code which uses nashorn to call into a specific interface exposed in clojurescript which knows how to render html, check if a url is canonical, redirect or compute initial state and render html for that state, and some other minor things. However it does constrain the way you structure your clojurescript application, for example Ajax has to happen in a certain structured way to make this work smoothly. Really the only tricky bit is getting the builds structured just perfectly as not all browser dependencies work in nashorn (no dom). There are five build targets: dev-browser, dev-server, prod-browser, prod-server and figwheel. Debugging sucks.

Matthew Phillips

unread,
May 21, 2015, 11:06:56 AM5/21/15
to clojur...@googlegroups.com
Ah, interesting. Would definitely love to see some sample code when you have the time.  Specifically the bits about calling into nashorn from an interface exposed in ClojureScript, I haven't seen this done before and would be interested to see how that works.
 
 
On Wed, May 20, 2015, at 04:15 PM, Dustin Getz wrote:
Yes, 99% of the application logic is defined in clojurescript e.g. Routing and Ajax queries, there is a very small amount of JVM code which uses nashorn to call into a specific interface exposed in clojurescript which knows how to render html, check if a url is canonical, redirect or compute initial state and render html for that state, and some other minor things. However it does constrain the way you structure your clojurescript application, for example Ajax has to happen in a certain structured way to make this work smoothly. Really the only tricky bit is getting the builds structured just perfectly as not all browser dependencies work in nashorn (no dom). There are five build targets: dev-browser, dev-server, prod-browser, prod-server and figwheel. Debugging sucks.


Matt Ho

unread,
May 21, 2015, 11:21:13 AM5/21/15
to clojur...@googlegroups.com
@Khalid check out

https://github.com/savaki/reagent-nodejs

It's 100% Node/JavaScript, no Nashorn and the majority of the code is used on both server and client side. I opted to separate the small server/client stubs into separate directories, but I suppose there's no reason it couldn't be replaced with a

(on-server ....)
(on-client ...)

Server side, it's just standard node tools like express and st.

M

Khalid Jebbari

unread,
May 24, 2015, 5:34:58 PM5/24/15
to clojur...@googlegroups.com
The following book isn't our yet, but it's written by a real javascript expert. Pretty sure we will find inspiration to do isomorphic CLJS apps.

https://leanpub.com/learn-javascript-react-nodejs-es6/

Marc Fawzi

unread,
May 26, 2015, 10:04:56 AM5/26/15
to clojur...@googlegroups.com
Currently, this is at the very top of HN news




On Sun, May 24, 2015 at 2:34 PM, Khalid Jebbari <khalid....@gmail.com> wrote:
The following book isn't our yet, but it's written by a real javascript expert. Pretty sure we will find inspiration to do isomorphic CLJS apps.

https://leanpub.com/learn-javascript-react-nodejs-es6/

Marc Fawzi

unread,
May 26, 2015, 10:30:35 AM5/26/15
to clojur...@googlegroups.com
The Horror!! I think after reading about that new "better than React" framework, I'd definitely want my isomorphic clojurescript framework to be React based. I made a pitch for Om/Reagent in that thread ;)



 
Reply all
Reply to author
Forward
0 new messages