yrby

Ruby · Rails · Yjs · MIT

Collaborative editing, inside your Rails app.

Your users edit the same post and see each other's changes as they happen, the way they do in Google Docs. yrby syncs the edits over Action Cable and saves them in your database. There's no Node process to run and no third-party service holding your data. For drop-in Action Text support with Lexxy, use lexxy-realtime.

$ bundle add yrby-rails
$ bin/rails generate yrby:install
you · /posts/42/edit
Writing together in Rails • Edits merge without conflictsada • Saved before anyone sees them
ada · /posts/42/edit
Writing together in Rails • Edits merge without conflicts • Saved before anyone sees themyou

This is a scripted replay. The demos are live, so open one in two windows and type in both.

How it works

Put the tag in a view where the user is allowed to edit the post. The tag includes a signed token for @post.body, and the browser uses it to subscribe to the gem's channel. The channel saves each change to your database before it sends the change to anyone else. Any Ruby code in your app can load the saved body, for search, emails, or plain HTML.

In the browser, you import the client and attach your editor once the Yjs document has synced. Any editor with a Yjs binding works.

Getting started →

app/views/posts/edit.html.erbview
<%= collaborative_document_tag @post, :body %>
app/javascript/application.jsbrowser
import "yrby-client/element"

document.addEventListener("yrby:synced", (event) => {
  const { doc, signal } = event.detail
  const editor = attachEditor(event.target, doc)
  signal.onabort = () => editor.destroy()
})
anywhere in Rubyserver
doc = @post.collaborative_document(:body).y_doc
Y::Lexxy.new(doc).to_html  # or read_text / read_map / read_array

Packages

The project is split into a few packages. Most Rails apps need yrby-rails and yrby-client. If your editor is Lexxy, lexxy-realtime installs both and does the editor setup for you.

yrby gem
Ruby bindings for y-crdt, the Rust implementation of Yjs. It includes the Yjs document type, the sync protocol, and HTML renderers for Tiptap and Lexxy.
RubyGems Source
yrby-rails gem
The Rails integration. It includes the document channel, the Active Record models, the view tag, and the install generator.
RubyGems Source
yrby-client npm
The browser package. It includes the yrby-document element and a Yjs provider for Action Cable and AnyCable.
npm Source
lexxy-realtime gem + npm
Collaborative editing for Lexxy, Basecamp's Action Text editor. It's built on the three packages above.
RubyGems Source

Demos

Each demo is a public room running on this site. Open one in two windows and type in both. Every demo also shows what Ruby reads from the saved state.

  • Y.XmlText Lexxy

    Basecamp's Lexxy editor. After each change, the server renders the document to HTML and saves it to a record.

  • Y.XmlFragment Tiptap

    Rich text with Tiptap's own collaboration extensions, including other people's cursors.

  • Y.Array of row Y.Maps Spreadsheet

    Each cell is its own Y.Map, so edits to different cells merge. Each window sorts on its own.

  • Y.Map of Y.Maps Whiteboard

    Sticky notes you can add, drag, and edit together.

  • Y.Array of Y.Maps Kanban

    Moving a card changes one field, so two people can move different cards at the same time.

  • Y.Text Code

    CodeMirror 6 with y-codemirror.next, including other people's cursors and selections.

Status

yrby is pre-1.0. The current releases are yrby 0.8.1, yrby-rails 0.7.0, and lexxy-realtime 0.7.1. Minor versions can still change the API, and the changelog marks breaking changes.

It needs Ruby 3.4 or newer. Precompiled gems are published for common Linux, macOS, and Windows platforms, so most installs don't need Rust.

yrby is built on y-crdt, Magnus, and rb-sys, and it speaks the same protocol as Yjs. It's written by JP Camara and released under the MIT license.

Bug reports and questions go in GitHub issues. Pull requests are welcome, and CONTRIBUTING.md explains how to run the test suites.