DEV Community

Stefan Buhrmester
Stefan Buhrmester

Posted on • Updated on

ActionStore: Real-time Svelte stores for Rails

Hey there,

in this post I'd like to introduce ActionStore, a new way to build real-time applications with Ruby on Rails and Svelte. It's still experimental and far from a 1.0 release, so expect lots of bugs.

TLDR: ActionStore allows you to push real-time updates into Svelte stores from your Rails backend.

In the beginning...

Many years ago (around 2007), Rails introduced the concept of remote Javascript, a technique of sending raw jQuery scripts through XHR to update the DOM. This enabled a whole new world of new "web 2.0" applications without writing much Javascript.

Things evolved, and many new frontend frameworks emerged. One of these new frameworks was Svelte. It has an amazing community, and I stuck with it ever since.

With ujs gone, I wanted something that allowed me to push updates to the DOM from the backend, but having those updates rendered by Svelte, instead of sending jQuery scripts. Preferably in real-time over ActionCable. The guys at Basecamp probably felt the same itch and have created HotWire to address it. But as explained before, I very much prefer component-based frameworks over sending server-side rendered HTML as is the case with HotWire.

Enter ActionStore

This is where ActionStore comes in. With ActionStore you can subscribe to ActiveRecord models via ActionCable, and push data directly into Svelte stores. When combined with Inertia it's probably one of the easiest ways to set up a real-time app with Rails and Svelte.

Example, please

Okay, let's start off by creating a real-time Svelte store using the subscribe method.

<script>
import {subscribe} from '@buhrmi/actionstore'

// you need the signed global id of the record you want to subscribe to
export let user_sgid

// Calling `subscribe` will set up an ActionCable subscription and return a 
// Svelte store which you can push to
const user = subscribe(user_sgid, {})
</script>

Hello {$user.name}

Enter fullscreen mode Exit fullscreen mode

Now you can populate this store from the backend:

class User < ApplicationRecord
  has_actionstore

  def subscribed channel
    push_update name: 'Rich Harris'
  end
end
Enter fullscreen mode Exit fullscreen mode

And now, whenever you push an update to the store, the DOM automatically updates. No matter if it is triggered by an HTTP request, or from a cronjob or background service. And by doing it this way, you also unlock the treasure trove of Svelte transitions.

This is exactly the way I always wanted real-time apps to work. There are a lot more things you can do with it. Check out the README for more examples.

If you end up using this for something, let me know :)

Take care, and as usual, happy coding!

Top comments (0)