"Reactive Rails"

So… there’s a hot new way of building “reactive” frontends in Rails that seems to have emerged as an option in 2020 and could be an alternative to rebuilding in React.

Just to be clear; I’m not saying we should definitely do this, and I absolutely recognise the timing couldn’t be much worse, but I think we should at least assess it, because there’s a chance it might be a much better option than going down the big React-rewrite path.

It uses a Rails-based system called StimulusReflex (a Rails gem), which is a combination of a few other technologies and gems that have been around for a while in Rails (ActionCable, Turbolinks, Stimulus), which are hooked up together in a novel way and with a layer on top that makes it easy to write the code to make it all work.

It’s not totally clear yet (it needs investigating) but it looks like it might offer:

  • All the benefits of a massive rewrite to a Javascript SPA-style frontend (like React) but without writing tons of Javascript
  • Better speed and performance than doing the same thing through a Javascript frontend
  • 10 times less code, and higher dev productivity in general
  • Incremental updates can be done on an existing Rails app, switching UI components one at a time
  • It’s done with a couple of gems and some very simple Ruby on Rails code

There’s a lot to unpack in this and lots of pros and cons to be a) determined and b) argued over…

Anyway, the docs are here, there’s a very simple video example of what implementing this actually looks like here, an article talking about it here, and a live example of a searchable/filterable table using it here.

3 Likes

This does look pretty exciting to me. It’s not so much an alternative framework to React, but something that removes the need for it altogether. If you understand Rails you understand Reactive Rails (just my opinion).

I don’t have the full context on the decision to rewrite the front end in React, or what the plan looks like for rolling it out, but in general when I see “big rewrite” I get nervous… Reactive Rails looks like it would make it easier to roll something out incrementally.

Reactive Rails might also encourage us to move toward an API-centric mindset a bit more than React would, but I’d have to think more about whether there’s shared logic (even just conceptually) between RRails and API controllers.

It does feel like RRails is a little bit new on the scene, and React has been around longer and is probably a more mature ecosystem with more potential developers. However, like I said above, it’s my opinion that if you know Rails fairly well you will pick up RRails very quickly/immediately. So essentially the pool of potential developers becomes the Rails pool, which I would estimate to be larger than the React pool.

Reactive Rails seems like it encourages less of a division between front and back end, which I think is a Good Thing since it means more people comfortable with working on more areas of the application.

One area of concern I can think of is browser/device compatibility: how well does something like ActionCable work on an older browser, or a “weird” device, or a slow connection?

And the other area of concern - can we even use all this new goodness while we’re still on rails 4.x?

Thanks for bringing this up @Matt-Yorkley!

1 Like

browser/device compatibility: how well does something like ActionCable work on an older browser, or a “weird” device, or a slow connection?

There are multiple issues that Javascript apps face in this case:

  1. initial download and bootstrapping of the framework and app can be painful on an old device or slow connection and the app can’t start until it’s done
  2. lots of extra processing power required on the client side
  3. lots of connections (and roundtrips to the server) and data transfer needed for the app to work

In all of these cases I think there would be a drastic improvement with this StimulusReflex / “Reactive Rails” setup. Basically we would avoid all of these problems and the speed and user experience would be significantly better, because: there’s no big upfront Javascript payload to be loaded, no significant JS bootstrapping to be done (with loading spinners?), almost zero client-side processing going on, and the techniques used in transferring data to and from the client uses methods that are designed to minimise data transfer and latency. I think there’s some caching-and-diffing techniques under the hood to minimise the amount of data used (which is just sent as HTML strings), and the data transfer is done over Websockets, which are fast and full-duplex connections (not your grandma’s HTTP).

older browsers

For significantly older/outdated versions of browsers it could be problematic. The technology is using Websockets which require relatively updated browsers. IE 7 is definitely out :laughing: Having said that, Websockets are widely used by a lot of applications and websites these days.

can we even use all this new goodness while we’re still on rails 4.x

Nope. We would need to do a bit more Rails-upgrading first, to 5.2. It’s 3 steps, and I think 4.2 -> 5.0 would be medium (there are no other 4.x versions between), and 5.1 and 5.2 would be tiny.

It’s not so much an alternative framework to React, but something that removes the need for it altogether.

Exactly!

1 Like

In regards to Javascript web-apps having the following problems (that are significantly worse on slow devices or connections):

  1. initial download and bootstrapping of the framework and app can be painful and the app can’t start until it’s done
  2. lots of extra processing power required on the client side
  3. lots of connections (and roundtrips to the server) and data transfer needed for the app to work

The accepted solution to these problems in the SPA world (preempting Luis here) is to add server-side Javascript rendering on top. What does that look like?

The idea is basically that you add a mini node server running a javascript-rendering engine alongside your backend that mimics the javascript processing that would be done in the browser and then offload bits of the javascript-processing workload to that engine as different requests are coming in, and then pass back the processed output to the client side (probably through an additional framework on the client end to handle the process and a modified routing layer).

This goes a long way to mitigating the above-mentioned issues, but it adds a lot of additional complexity to the stack. The frameworks and technologies for doing this are relatively new and are still changing and evolving.

So if there’s an opportunity here to both a) completely avoid these problems in the first place, and b) completely avoid the need to implement the complex solution to those problems, and still end up with a lightning-fast, reactive UX with real-time updates to the DOM (which is the whole point of doing an SPA-style app in the first place), then that is very exciting…

The main technologies used here are; ActionCable (for Websockets) which was merged into Rails core 5 years ago, and Stimulus (a tiny bit of Javascript for triggering simple requests from DOM interactions) which has been around for at least 3 years and used by the Rails community. These are combined into something called CableReady (which is newer, and basically directs those simple requests triggered by Stimulus back to Rails app routes, through Websockets). The whole thing is wrapped up in StimulusReflex which basically just adds some nice classes that give a Rails-like structure to the code.

On a slightly separate note, there’s actually a lot more that would be enabled by this framework (with a bit of extra work), for example it can do live, asynchronous, broadcasted push-updates (with DOM changes) to multiple clients simultaneously with a few extra lines of code (if you’re into that kind of thing). There’s a quick video demo of what that looks like here but this stuff is more of an optional extra and not something that would be required at all for making a nice reactive UI.

Another concern from Luis’s side (maybe the main concern? :sweat_smile:) is whether or not this would force API-first development in general as a happy side-effect (React would definitely do that).

I’m pretty sure we could do it in a way that directly re-uses the same RESTful actions from API controllers in the “Reflex” controllers, but it needs a bit of investigating.

One of the main dimensions here I think is a preference for rails apps vs a js app. My personal opinion is that js is as a valid tech as rails, including for server side code. I know this is not the perspective for everyone. I am saying this just to put that in perspective.

As said on slack, we would really need to halt the hiring process as we are specifically hiring for react devs.

I dont think adoption of react is a massibe rewritte, quite the contrary, it’s just a new way of doing things that would replace the old one. Just like this solution here would also be a new way of doing things that would replace the previous ways. It will be progressive in both cases.

I have no clue how this would work with our API endpoints to fetch data. Would it work with those endpoints, that would have to be clarified. From the video it looks the micro endpoints are auto generated? I dont think that would work for our main api endpoints.

Also, how would this play with CSS and styling frameworks in general?

Another major concern I have is around maintenance and support longevity, react is 159k stars on github, stimulusreflex is 1.5k. Why would we take the risk of adopting a brand new technology?

This is a huge proposal. I’d like to see a list of pros and cons to each. If folks add their own lists of pros and cons we can aggregate.

React

Pros

  • Widely used, supported, tests.
  • Industry standard so loads of skilled folks out there. Easily to find contributors and hires.
  • (Luis) react devs are FE devs that bring FE/UI focus (CSS anyone?) to OFN. This solution here will make OFN a ruby server side only team which means FE/UI will continue to be a stretch for the mostly backend devs.
  • (Luis) API focus - react will naturally strength the usage of the API - the relation between reactiverails and api still needs to be clarified.

Cons

  • We don’t have the skills required within the team. Devs will need to learn react and we need to hire (which we have almost got to the end of this recruitment process)

Reactive Rails

Pros

  • Seemingly uses Rails meaning that it will be easier for our existing devs to pick up and work with (?)
  • A range of bold and potentially untested claims about how fast, slick, superior it is in every way

Cons

  • Small user base. New tech. Not stood the test of time.
  • If we go down this path our existing recruitment process is defunct as we’ve been recruiting react devs and none have rails experience.

I think the main technology that’s doing the work here is ActionCable, and as I said it was merged into Rails core 5 years ago and has been included and active in every Rails application since version 5.0 was released. It’s been used very widely for a lot of different kinds of things, for example; rich-featured live-chat inside a web browser session (which requires push capabilities and Websockets).

Matt, I would disagree there. ActionCable is how rails handles websockets. ReactiveRails is something that builds on top of it and has quite a lot more to it than just websockets (from my very limited understanding: the extra syntax on the templates, the hooks/methods and the JS generation).

Lynne, I’d add two pros to react:

  • react devs are FE devs that bring FE/UI focus (CSS anyone?) to OFN. This solution here will make OFN a ruby server side only team which means FE/UI will continue to be a stretch for the mostly backend devs.
  • API focus - react will naturally strength the usage of the API - the relation between reactiverails and api still needs to be clarified.
1 Like

Should we really put this one into the list? I understand it’s a pain, but it would perhaps be better to compare the two technologies aside of our recruitment process?

1 Like

I would be happy to remove sunk costs of existing recruitment, but should we then add the additional cost of the alternative eg Reactive rails requires restarting recruitment for FE role. The economics of this is part of the decision making process even if basing on sunk costs is flawed.

1 Like

are we planning to talk about this in our ‘making FE dev decision’ meeting tonight / tmrw morning? If yes then would be very useful for @Matt-Yorkley to be there (I think @sauloperez and @luisramos0 already coming) - in global calendar

Here’s my list of pros/cons:

React

Pros:

  • Well established (relatively speaking) tech
  • Large hiring pool
  • Lends itself toward forcing us to create and dogfood a full fledged API

Cons:

  • Encourages specialization of developers into those who can only touch Front End bugs/features vs Back End.
  • Costlier if it means having a developer specifically dedicated to understanding/writing/maintaining React code.

Reactive Rails

Pros:

  • Less code to accomplish the same thing
  • Faster initial page loads
  • “Rails-y” (see below)

Cons:

  • Not as established/proven
  • Can’t use it until we upgrade to Rails 5.2
  • I think there is something to be said for having to restart a search for an additional developer, even though it’s a sunk cost

The part about Reactive Rails being “Rails-y” is the hardest to explain but to me it’s a big point in favor of Reactive Rails. I am fully aware of my own bias here, but there’s something about looking at the code examples written in Reactive Rails. I look at the code and I know exactly what it’s doing. I don’t need to look at a manual, or read the documentation. It is expressive in the same way Ruby is expressive.

This isn’t because they’re simple examples either; when I look at ToDo list code samples for React, I understand them, but I have to remind myself (or look up) what patterns or conventions are being used.

I can’t make that meeting that @Kirsten mentioned (1am for me) but I can watch later if it’s recorded.

There have been some good points on both sides. I agree to all the pros-cons lists. And there were a few questions I would like to dive into:

Support of older browsers

Very old browsers may not support web sockets which makes the ActionCable component not work. So if something is updated on the server, for example stock runs out, the client is not notified. They only see the result with the next page load. That’s just as good as what we have now.

API first

The whole point of Reactive Rails is to render the view on the server with Rails. So I guess that the server response mainly contains HTML and not JSON. It would not contain an easy to use data representation. Bad news for our API development. It would be much easier and more efficient for our application though. No detour via JSON. And maybe the breaking down into components would still help us to develop a good API, separately.

In reality, I suspect that we will always need a separate API anyway. Otherwise all 3rd party integrations will break when we change the API for our application. It would just be easier to create a new version of the API from the existing master API used by the application than creating a completely new one from feature requests by outsiders.

Does Reactive Rails replace React?

There are many cases where Reactive Rails can do the job and is much easier. But it won’t always be the best solution out of the box. We will still need some custom javascript on the client side for the best user experience. So I’m wondering if we will have both, React and Reactive Rails. The big question is on the server side: Do we render HTML with Rails or with React? Because not rendering HTML on the server at all is too slow on the client, especially on initial page load.

My personal summary

I’m very excited about Reactive Rails and the Stimulus Reflex project. It can save us a lot of code and complexity. But I also see the danger of not using our own API. I personally would build with Reactive Rails. That may just be because I’m more familiar with it. And I definitely can’t give a sound recommendation because the technology is so new. I would like to know what Github developers are planning… they have a great API and a great reactive UX.

P.S.:

The fact that this decision may de-rail our hiring process rings an alarm bell for me. Did we really want to hire a React expert who would be useless with Rails? Or do we want someone who is good at front end development, has experience with React but would have no problem to learn something new or combine technologies? Does any of the candidates fit in there? That’s off topic here though.

2 Likes

do we want someone who is good at front end development, has experience with React but would have no problem to learn something new or combine technologies?

Yes! I think we absolutely need that person, regardless of which choices we make.

I would like to know what Github developers are planning

Github is an interesting example (a modern Rails app with ~22 million users!). They made a conscious decision to actually move away from Javascript (they spent a lot of time decoupling from their old JS and reducing it to a minimum) and rely on HTML rendering as much as possible with a few technologies like Turbolinks sprinkled on top to add modern UX features with the least complexity possible.

Basecamp’s flagship email service hey.com has launched recently and is very much going in that same direction (and doubling down on it). There are slated to be some major new releases of things like Turbolinks 6.0 coming in the very near future, and we could probably take advantage of them if we modernised our Rails version a bit.

This goes against current received wisdom, but; I think 2021 could be a very exciting year for Rails and we might see an upswing in startups choosing it for their stack (this has been a downward trend for years now) alongside lots of new developments in the space.

Just to be clear, I think we should definitely focus on our API in 2021 (either way) and get it to a point where external apps and services can genuinely use it. I would like to see that driven to some extent by actual use-cases.

Whichever direction we go in, I’m excited the idea of any kind of roadmap where we :fire: all of our legacy Angular code, update our prehistoric admin UI, and get our API to a point where it can be useful for external clients.

There’s also some other possibilities if we went with this “Reactive Rails” thing, for example we could start incrementally using it in the shopper-facing parts of the app to ditch our legacy Angular code there too and get some serious enhancements to speed and UX, with very small amounts of work and very simple code. I’ve had a go at using this locally with a quick Rails 5.2 app and it genuinely is as easy at it looks in the videos I’ve linked.

1 Like

Some actions from our quick meeting about this:
[] @Matt-Yorkley to do POC with Reactive Rails
[] We will make a decision on tech strategy by 11 Dec 2020, aiming to hire by January 2021 if not before.
[] I am NOT clear who is responsible for getting us through a process to make this decision by 11 Dec - I think it is @sauloperez or @Matt-Yorkley? It is not purely a tech decision, must also (obviously) involve product as implications for API are very significant

This is the public/private API discussion we had in some other discourse post.
I tend to think OFN will have a public API when it is larger and more adopted, the first few years I think we should go single API because it’s so much cheaper. Build the app in the api and make that api public. When things get bigger, more external clients, create a public API that is more stable :+1:

Wait, this only works in rails 5.2? That would mean if we decide to go this way and not the react way we would have to upgrade to rails 5.2 first? How would we start the dev of the network feature in the beginning of 2021?
Rails 5.2 is 3 upgrades away from 4.2, even if we focus on it it would take at the very least 1/2 weeks for each upgrade, something like 1.5 months of dev time at least. In terms of delivery that would easily double. If we start it in Jan 2021, you get it live by April. This is the best case scenario, it feels a bit unrealistic. More realistic is that if we need rails 5.2 for this we would be able to start network feature on the second half of 2021 after three more rails upgrades. Is this correct Matt?

Yes, that’s one of the factors. As I said, I think it would be one medium and two tiny Rails upgrades, and we’d get other benefits from being on a modern version of Rails.

ok :+1:
Yeah, it’s a major benefit the rails upgrade, but also a major draw back or the delay it may cause. I am not 100% sure how soon the network feature/product uplift work is planned to come into the pipe.

I am thinking about clarifying what API first means: starting the product uplifet project, with the react approach, we would focus first on cleaning up and clearly define what the products API endpoints (CRUD) would look like. This endpoint would have to serve both the new uplifted product page as well as external clients wanting to access the product catalog. After that we would build the new react app on top of this API. Quite a few things need to be decided in terms of how to build the react app :+1:

On the reactive side, we would have to upgrade rails and build the new uplifted product page using rails (one of the main points for me is that this is really the opposite direction of API because even the list of products would not be fetched from the json API as it is today with angular, so 0% API dogfooding).
API would become a product feature and would require specific initiatives and budget to drive it, potentially never coming. In this case an initiative to rebuild the products API would have to be prioritized.

I am clarifying this because it makes it clear this is not just a tech decision, it’s a strategic decision and will influence the way the product evolves.

I think I am done here, I am happy my last comment is about clarifying what API first is :slight_smile:

1 Like