Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Re-Frame Guide: Front-End Architecture in Clojure (purelyfunctional.tv)
156 points by kimi on July 8, 2017 | hide | past | favorite | 30 comments


At Collecture.io, we love re-frame about as much as we love Clojure and Emacs^^

Thanks to re-frame we have exactly the same logical FRP abstraction and Code in our Android, iOS and Web Application.

It's a great framework to work with - can only recommend it. That is, if your application has a minimum in complexity. Because otherwise Reagent with a global atom will work just fine and be a lot less complicated. So don't introduce it when working on your first CLJS code base. Similarly you probably don't need Redux to your React in your first JS SPA.


Are you using any Clojure in your mobile apps, or mainly on your web properties?


Would love to know people's experiences of using Reframe in production.

Is the additional structure it imposes on the app worth the complexity it adds in learning the framework?


My team switched to re-frame after about 6 months development, and our only regret is that we didn't do it sooner. It took about a week to switch over, and caused minimal friction. The complexity it introduces is minimal, but it makes things more predictable when it comes to rendering, and it goes a long way to help with organization.

The big advantage of using re-frame in my opinion is that it provides really clean MVC semantics for Reagent. All the changes to the model go through controllers created with reg-event-db, and then the view observes the model via reg-sub subscriptions. With this approach, you can easily tell how the events update the model and interact with each other because they're all in one place.

You can see a real world app using re-frame here https://github.com/yogthos/memory-hole and I don't think it's any more complex than it would've been using plain Reagent.


How much Clojure was the team exposed to before the switch?


Well, they most probably have programmed in Clojure before. Because otherwise introducing re-frame doesn't make too much sense. Plus, you're speaking to the creator or the great Clojure Web framework luminus which I can recommend highly from personal experience in multiple projects.

https://github.com/luminus-framework/luminus


My team has been using Clojure for about 6 years now, but we only started introducing ClojureScript last year. Figwheel and Reagent workflow was what sold us on it.


I notice that you recommend figwheel a lot, I wanted to ask you: Have you ever tried the boot tooling (boot-cljs, boot-cljs-repl, and boot-reload) and if so do you have any opinion on it vs leiningen+figwheel?

So far I've personally found boot a lot easier to work with than leiningen and the cljs repl is easier to get going and integrated with CIDER.


I have very little experience using boot. The main benefit of Figwheel is that it allows you to retain the state while hot loading code. I find this makes a really big difference when working on complex UIs. I can get the application in a particular state, and then tweak the UI in that context.

There's a https://github.com/boot-clj/boot-figreload plugin that adapts Figwheel for boot, but I haven't used it myself.


Ah, I was just wondering if you had experience there.

boot-reload[0] replicates everything figwheel does in terms of hot reloading the cljs. I started using boot because I wanted better tooling for cljs, which I think it provides. I wanted to ask if you had any experience with it because I know you have a lot of experience with cljs and was wondering if you had any insight into potential hidden costs.

I agree that hot reloading is a huge upgrade over the old workflow, it saves so much time.

0: https://github.com/adzerk-oss/boot-reload


Ah I see, and yeah I haven't really used boot since I already got comfortable with lein by the time it came out. It sounds like they both work pretty well nowadays though.


The main thing preventing me from using Clojure on the backend has been that db libs (pgsql, mysql) seem to not be under particularly active maintenance/development, which also feels at least somewhat true for other libs in the ecosystem. HugSQL as recommended by Luminus hasn't seen any development in the last year. What's been your experience here?


All the heavy lifting is done by the JDBC drivers implemented in Java. These are mature and very stable. Clojure libraries wrapping these drivers simply provide a more idiomatic API to them.

I'm not sure which db libs you've looked at, but the most used one is https://github.com/clojure/java.jdbc and it's just a wrapper for the Java JDBC API. The Postgres/MySQL connections are managed by the official org.postgresql/postgresql and mysql/mysql-connector-java driver libraries.

HugSQL hasn't seen much development, because it works well. I'm using it in all my projects, and it's been working perfectly for me. The library has a fixed feature set, which is taking SQL templates and generating functions that make JDBC calls based on them. Now that it's feature complete, the only time you'd see changes would be if the underlying API changed, or for a bugfix. The last commit actually happened 28 days ago, and it was a bump in dependencies.

Just because the repo isn't active is not an indication that the library is abandoned. My experience with Clojure libraries, is that this is usually an indication that the library works well and most bugs have been ironed out. Looking through the issues is generally a better approach of checking the health of the project I find.

If stability of database connection libraries has been your concern, I can assure you that it's misplaced.


Thanks for the reply! What would you recommend if I wanted something with a query-builder style API? In my head it seems like clojure would be a really great fit for that as a modular way to build statements.


I would recommend taking a look at https://github.com/jkk/honeysql that uses Clojure data structures to represent SQL statements. It's similar idea to Hiccup for HTML.


I think the structure it enforces is pretty minimal compared to many of the current JS frameworks. It doesn't take so long to get used to. Definitely much less overhead than redux in my experience. It boils down to 3 basic concepts.

I've made some moderately sized apps for it. Re-frame is incredibly productive and fun to use for a variety of things in my experience. The abstractions sometimes leak a bit (side effects can be difficult to make happen cleanly) but for most tasks it lends itself to really solid architecture.

I think they underplay how important the "form-3" components can be for complex apps (where you use more explicit lifecycle hooks) because JS events are frequently necessary, and they're required when you need to make use of raw JS libs.

Debugging in cljs is trickier than JS overall, which isn't surprising, is the real downside. But imo cljs fits a lot better into the reactive/immutable patterns that people are aiming for in the front end world these days.


You no doubt know this, but just in case ... Dirac completely transforms that CLJS debugging experience (in a positive way): https://github.com/binaryage/dirac


Yeah, I've seen it. The overhead for making it work is definitely a tad on the high side (through no fault of the devs that make it). Either way it's really swell though.


Tl;dr: yes.

In practice, it depends, mostly on the size of your app. It's one of the cases in which TodoMVC is too small to make the framework shine properly. You're going to love it especially when your app starts to get bigger (and the complexity of "real world" starts to creep in) and the small complexity of the abstraction that you added in the beginning pays off. This is because you have a framework to put the new stuff in, but it doesn't get in the way.

This is the opposite of what I usually felt with the other js frameworks I worked with (Angular, Backbone, React doesn't count because not really a framework), in which once your application scales in size its complexity terribly increases.


Been using re-frame in production since 2 months. Lost some hair in the first 3 days ( had to make some db structure decisions based on requirements) but after that it's been amazing and adding new features has become really trivial.


I know nothing about Re-Frame but something seems not quite right about a front-end framework having an affect on database structure.


Not a bad intuition to have. But with some reading you can learn that "db" refers to the in-app, in memory (or local storage) database, which is designed to hold all your application state, which allows it to be clearly transacted against and referenced from anywhere in your app.

You start writing pure functions which take the current "app-db" as an argument, and return what the "app-db" should be. If React is `v=f(s)` (view is a function of state), re-frame is `s=f(s,e)` (state is a function of the previous state, and events)


re-frame still has v=f(s). It just has more than just a view layer.


You know nothing about software architecture if you think that you can't optimize a software performance/responsiveness changing the way you store/normalize/retrieve data.


I know that I wouldn't want the choice of a fly-by-night front-end framework influencing how that's done with a back-end database. But, looks like I made the wrong assumption about the db structure that was influenced, I guess we have front-end databases now, which is an interesting idea I will be exploring furtherer.


It does more than just add structure, it also improves performance.


The best re-frame guide I've seen so far.


I've been using elm in production and it's been a great experience. I've never heard of re-frame (and never used cljs); could someone with knowledge on both give me a quick comparison between elm and re-frame?


One notable difference between Elm and Clojurescript in general is that Elm has very limited interaction with the whole front end ecosystem, where as in Clojurescript you can do anything that the JavaScript guys could do. Elm's ports don't really do much in that area. Clojurescript respects developers to access all the power that browsers can offer you, if you want it.

Another big difference is that Clojurescript can be passed through advanced optimizations, but Elm does not support those. But in Clojurescript, most projects are already setup for optimization out of the box. This is the same optimization that Google uses for all of its services such as Gmail, Google.com, etc. And it is industry-leading.

The final notable difference is that most work in Clojurescript uses figwheel, which greatly accelerates front end development with it's automatic reloading of what you work on as you save it, as well as other information it provides. Elm has attempted something similar, but it's quite limited and doesn't support a lot of the complex stuff you might want to do in Elm, and Elm's documentation says only to use it for basic tasks.

There is also the re-frisk tool for re-frame which gives you super easy visual inspection of your entire application state in a graphical tree, quite useful.

All that said, Elm as a language is very attractive. But as an advanced development platform, it doesn't go nearly far enough. Perhaps one day it will.


No direct knowledge of elm, here's what the framework author had to say (briefly) on the topic: https://github.com/Day8/re-frame#why-should-you-care




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: