yrby

Ruby · Rails · Yjs · MIT

Collaborative editing, inside your Rails app.

Your users type in the same document and see each other's changes as they happen, the way they do in Google Docs. yrby syncs it over Action Cable and saves it in your database. There's no Node process to run and no third-party service holding your data.

$ bundle add yrby-rails
$ bin/rails generate yrby:install
you · /posts/42/edit
Launch checklist for Friday • Tag the GitHub releaseada • Publish yrby-client 0.6.0
ada · /posts/42/edit
Launch checklist for Friday • Tag the GitHub release • Publish yrby-client 0.6.0you

A scripted replay. The demos are live: 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. It includes a signed token for @post.body, and the browser subscribes to the gem's channel with it. The channel saves each change to your database before sending it to anyone else.

In the browser, you import the client and attach your editor once the document has synced. Any editor with a Yjs binding works. On the server, Ruby can read the saved document directly, for search, emails, or plain HTML.

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. Documents, the sync protocol, and the Tiptap and Lexxy HTML renderers.
RubyGems Source
yrby-rails gem
The Rails side: the document channel, the Active Record models, the view tag, and the install generator.
RubyGems Source
yrby-client npm
The browser side: 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. Built on the three 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 document.

  • 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.