Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

So I'm just at the tail end of a project where I'm attempting to build a collaborative text editor, and it's been absolute hell. I figured it would be a tricky problem, but I had no idea how far down the rabbit hole goes. I kept thinking, gosh, there's gotta be a backend service that bakes this in, if there isn't it would be a great business opportunity.

I almost want to scrap all of my code and move it to Supabase. Congrats to the team on this launch, very cool.

edit: actually, after thinking it through, I'm not clear on what Supabase is calling multiplayer. Presence is one thing, but when I think multiplayer, I'm thinking conflict resolution. Is this an OT/CRDT implementation? Or is it just presence?



One thing that... might be useful depending on what exactly you're building here is https://hocuspocus.dev, which is an incredibly easy to use server for Y.js.

It's written by the team behind https://tiptap.dev, which is an amazing WYSIWYG text editor, but HocusPocus does a great job of syncing state of a variety of WYSIWYG editors out of the box. Getting the server running is a couple of minutes worth of work and scaling it is quite easy.

In addition to editor state, it also has built-in support for 'Awareness' (info on current users), as well as any other Y.js datatype, including other things with a bridge into Y.js.


Related to this is also an example from ProseMirror (which TipTap uses as the editing component) [0][1]

I'm not completely sure, but I think at ProseMirror they're using Yjs [2] for the collaborative editing part. If not, checking out Yjs is worth it in and of itself.

> Yjs is a CRDT implementation that exposes its internal data structure as shared types. Shared types are common data types like Map or Array with superpowers: changes are automatically distributed to other peers and merged without merge conflicts.

> Yjs is network agnostic (p2p!), supports many existing rich text editors, offline editing, version snapshots, undo/redo and shared cursors. It scales well with an unlimited number of users and is well suited for even large documents.

> Conflict-free replicated data types (CRDT) for collaborative editing are an alternative approach to operational transformation (OT). [3]

OT was what Google Wave was based on and I think current colab editing in Google Docs and other of their office products use this.

[0] https://prosemirror.net/examples/collab/#edit-Example

[1] https://marijnhaverbeke.nl/blog/collaborative-editing.html

[2] https://github.com/yjs/yjs

[3] https://github.com/yjs/yjs#Yjs-CRDT-Algorithm


> I think at ProseMirror they're using Yjs

No, ProseMirror has its own approach to sync.

> OT was what Google Wave was based on and I think current colab editing in Google Docs and other of their office products use this.

Yep.


ProseMirror has its own OT system developed by its lead developer. However the developer behind Yjs has created Yjs bindings for it that are first class!

The team behind TipTap (built on top of ProseMirror), created the Hocuspocus server backend for Yjs and collaborative text editing.


We use tiptap/hocuspocus at Vowel (https://www.vowel.com/) for our collaborative notes editor. It's really slick!


Ha, that's good to know -- I've been enjoying using Vowel and was wondering what the in-call notes editor was powered by. Vowel is really slick too -- nice job! :)


Very nice. One of my hard requirements is that the data itself has to be persisted as a string.

So I’ve had to implement a system where a new yDoc is created when the session begins, and then is converted back into a string when the session ends.

Did you have to do anything similar? And if so was it easy with hocuspocus? I wasn’t able to get a clear answer from the docs.


Ooh I like your product.


I'm using TipTap actually, but decided not to go with hocuspocus since it's in beta (at least that's how they position it).

edit: also, I couldn't get a good look at their documentation outside of the paywall, so I have no idea how they implement the backend. It's important, because I need to persist my documents as html strings, not as y docs.


Just so you know, I've used it since the early part of this year and found it to be robust and fully-featured (most functionality comes from Y.js after all), but definitely defer to them on how ready they consider it. :)


+1 for tiptap, and yjs, used both to build https://www.buildmemo.com 's collaborative editor. Did not use hocuspocus but found it trivial to implement our own node ws backend.


How are you persisting the data? Are you storing them as ydocs?


Just fyi your page has text headline cutoff issues on iPhone X


For a collaborative text editor, you need two things: (1) a full-stack system that maintains a running list of data events such that everyone sees everyone else's events eventually, and (2) frontend code that adapts that set of events, along with your text cursor position and current changes, into a cohesive view of a document at any moment in time.

Supabase and Replicache can absolutely help with (1). But for (2) you will need OT or CRDT.

https://docs.yjs.dev/getting-started/a-collaborative-editor is a good place to start - it uses Quill and CRDTs for (2) and can have a persistence layer built in (or custom written, to work on top of Supabase etc.) for (1).


Quill Deltas are a very interesting concept, I used Quill myself along with Supabase for realtime sharing (not collaboration) of text and it was almost a breeze.


Several teams use yjs on top of Replicache, it's a real easy match.


This is where Erlang/Elixir really shines.

https://elixir-lang.org/blog/2020/11/17/real-time-collaborat...

https://www.youtube.com/watch?v=HTB4mQyMAmg

And supabase uses elixir to listen to database changes and push then over websockets.


I think what you want is probably https://replicache.dev/


replicache has a great "Linear" example using Supabase: https://doc.replicache.dev/examples/repliear


do you have to load third party scripts with replicache?


No. All you have to do to use Replicache is embed the `replicache` npm package in your client-side code, and implement the expected REST interface on your server: https://doc.replicache.dev/guide/intro


They take rent


We'd like to ensure that Replicache continues to exist and that we can continue to support it. So yeah, we proudly charge for it.


It’s just a fact to consider in tradeoffs. There are several economic models that support tool businesses, or returns for investors. Please don’t take offense at noting which of those several valid approaches


Not offended. Our team has a long history in open source and have seen both the triumphs and challenges over the years. It's very difficult to build a sustainable client-side open source tool without some other business off to the side that supports it (example: nextjs/vercel).

I like the simplicity and clarity of just directly charging for the valuable thing. Nothing wrong with the other models, they just aren't for us.


Definitely feel your pain. We did a full OT implementation for our startup [0] and it was a beast. We based it on Slate.js which has a nice concept of operations that maps nicely to OT, but it was still a lot of work to get it working well (and there are still rough edges we try to improve all of the time). We did base it on Postgres in the backend so really looking forward to what the Supabase team comes up with going forward and seeing if they can help us delete some complex code :-)

Happy to have a chat on collaborative editing anytime if that'd be helpful (email in profile).

0: https://kitemaker.co


It’s broadcast and presence they have released, both building blocks for multiplayer. It’s unfortunate that HN rules meant a mods changed the title to the blog posts title. I had gone with a slightly edited (for length) sentence from the second paragraph as I thought it was clearer:

… general availability of Realtime's multiplayer features, Broadcast and Presence.


how does the pricing compare to liveblocks? was really offput by their pricing (charging $0.01 for every time a client connects)


Pricing is still tbd unfortunately. Currently every project gets these features with some limitations:

- 25 concurrent channels

- 25 channel joins per second

- 200 concurrent connections

- 100 broadcast messages per second avg over 60 seconds (not including db changes) (aka 6,000 per minute rolling)

I think these are probably pretty close to where we'll land for free projects. They can be changed per project so if you (or anyone) needs a limit increased in the short term we can do that.


Hi there,

Im Steven, co-founder of Liveblocks. Thanks for your feedback on pricing. We try to have a fair pricing for everyone and for companies of all sizes.

We’re working on a new pricing that will make this much more affordable, even free in most cases.

Would love to get your feedback on that if you’re up for it?

Thanks!


I haven't documented it yet, but my serverless board game platform supports collaborative text editing. I'm using Codemirror 6 which has a very simple operational transform scheme, and I baked Codemirror's OT scheme into my back-end. It works great, but this was because I had all the realtime stuff sorted out (connection management, multiplexing, etc...)

https://www.adama-platform.com/


I can definitely see how a company built on Elixir, like Supabase, would offer this as part of their product.

Phoenix Framework gives you presence and CDRTs out of the box. I’m not sure if they’re also using Phoenix, but there’s a well-known, heavily used open source solution for the core of this offering and I’d be shocked if they didn’t at least study and/or borrow from it.

Edit: yep, according to the page they’re advised by Chris McCord, the creator of Phoenix.


Fluid Framework looks interesting. Since it's open source you can either use a cloud service (Azure Fluid Relay) or run it on Kubernetes with Routerlicious. https://fluidframework.com/


How are you currently building the collaborative features? Using web sockets i imagine, right?


yeah, websockets + yjs + y-prosemirror


That sounds like a stack that should be up for the job. Used these myself and found making a collaborative editer with those quite a breeze actually. What issues do you have with them? Or did it just take a long time before arriving at that combination?


That combination kinda came by default, since I opted to use TipTap: https://tiptap.dev/

My real trouble is the fact that this is an existing application, with hundreds of thousands of pre-existing documents, all stored as html strings. I've been trying to extract the html on the server, but it's incredibly difficult. I've actually given up for the time being, and using a hacky workaround.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: