Is the additional structure it imposes on the app worth the complexity it adds in learning the framework?
Is the additional structure it imposes on the app worth the complexity it adds in learning the framework?
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.
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.
There's a https://github.com/boot-clj/boot-figreload plugin that adapts Figwheel for boot, but I haven't used it myself.
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.
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.
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.
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.
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)