Hacker Newsnew | past | comments | ask | show | jobs | submit | antics's commentslogin

The CEO says it's not: https://x.com/JustJake/status/2038799619640250864

A lot of people are confident in enough in their ability to spot AI infra that they are willing to dismiss a firsthand source on this, and I admit I have no idea why. There isn't any upside to making this claim, and anyway, I assure you that people need no help at all from AI to make these kinds of mistakes.


Their reply doesn't make much sense, they're supposedly soc2 compliant. How are they compliant but letting a single engineer push out a change like that?

I'm sure Claude didn't literally ship the feature itself with no oversight, but I also find it hard to believe that their approach to adopting AI didn't factor in at all. Even just like, the mental overhead of moving faster and adopting AI code with less stringent review leading to an increase in codebase complexity could cause it. Couple that with an AI hallucinating an answer to the engineer who shipped this change, I'm not sure why people are so quick to discount this as a potential source of the issue. Surely none of us want our infra to become less secure and reliable, and so part of preventing that from happening is being honest about the challenges of integrating AI into our development processes.


> I'm not sure why people are so quick to discount [AI] as a potential source of the issue.

Because (per the link above) the CEO said that (1) it was their fault, and (2) it had nothing to do with AI.

I understand that on this forum statements like this are inevitably greeted with some amount of skepticism, but right now I'm seeing no particular reason to disbelieve Jake, and the reason that "if they did use AI they'd deny it" should frankly not be considered good enough to fly around here. Like probably everyone in this comment section I'm open to evidence that they used AI to slop-incident themselves, but until we can reach that standard let's please calm down and focus on what we actually know to be true.


During this whole incident, Railway have made a wide range of misleading and straight out false claims to cover themselves, so them saying it wasn't AI is pretty much meaningless

Would you mind pointing out these claims? Happy to address them personally

Come on man, their CEO is a massive vibe coding proponent and his company spent $300,000 on Claude this month. But yeah, I'm sure Claude had nothing to do with any of it. I bet they don't use it to write any code.

https://xcancel.com/JustJake/status/2030063630709096483#m


Both things can be true: they’re doing a lot of vibe coding, and this was a human error that didn’t involve AI.

I have no skin in the game but that is a very charitable perspective.

> It feels a little weird to put 100 hours into something that won't be noticed by its absence. Exactly no one will think, "man this dithering is stable as shit. total magic going on here." I don't want to give people problems they didn't know they should have though so it was worth fixing.

I mean maybe it's just me, but that is literally the first thing I noticed and I appreciated it so much I instantly bought the game. I don't even play video games much!


I run a VC-funded startup. We fund the extremely high-quality OSS `react-prosemirror` project at > $10k a year. I really, really think you should too. Here was our thinking:

- Cheaper than a Tiptap enterprise license (essentially a 50% discount).

- Dramatically higher quality, in a way that is directly noticeable to users. The "naive" React/ProseMirror integration has terrible state tearing issues that make your text editor feel haunted. Cursors in weird spots, mismatched transaction errors, strange races that happen only sometimes, lots of `setTimeout` and `queueMicrotask` to patch over weird problems. The core issue is a little hard to explain, but React and ProseMirror both have a kind-of virtual representation of the DOM, and when that is updated, they figure out what changes need to be made to the DOM, and then execute them. But these cycles are completely incompatible. The solution is to rewrite the ProseMirror `EditorView` in pure React, which is what `react-prosemirror` has done. Tiptap did not do this, and it is empirically very challenging to manage as a result. I am happy to discuss more if people are interested.

- Collab on ProseMirror is in a very challenging spot, and this is the right team to work on it. Since we spend > $10k/yr funding the project, we have worked with them directly on this, and we know. We wrote about the alternatives in a recently-popular HN thread: https://news.ycombinator.com/item?id=47359712 although as god is my witness, I 100% promise we did not coordinate this in any way.

- Shane is one of the best engineers working in the frontend today. You want his attention, and it is worth paying for.


But Kevin, you never really answered the question of the article. Unless I need a truly-masterless p2p topology, why would I do all this stuff, including throw away editor intent around things like block split, just to use Yjs? prosemirror-collab and prosemirror-collab-commit already seem to do all the things the Yjs docs claim to do (unbounded offline writes that reconcile automatically, optimistic updates, tolerant of all kinds of failures), and they work with 100% fidelity to the underlying model. AFAICT, the only thing that you need Yjs for, is true p2p editing.

This is a serious question, and the question of the article. I am here to learn what you mean, please explain.


Yjs is about making things easy. It is a good abstraction to make anything collaborative (not everyone can implement something like prosemirror-collab).

I'd take the slight performance overhead any day if I get guaranteed syncs. Network protocols are not as reliable as you think they are. Detecting random drops of messages is hard. At scale, you are going to appreciate the sync guarantees.

prosemirror-collab doesn't give you offline editing either. Because, guess what - if there is no central server you can't edit the same doc from multiple tabs.

I once had a customer that accidentally deleted part of their database containing Yjs docs. Few of his users noticed, because their docs synced through y-indexeddb.

And it's fun. You can Yjs on anything. There is a company that syncs Ydocs through QR codes.

As a generic collab library, it does a very good job. CRDTs really are a fun thing to use. A lot of people feel that way.

If you want to use something else, that's totally fine! Write an article about how great prosemirror-collab is.


But Kevin, prosemirror-collab does give me offline editing. I use it literally every day, entirely without issue. I write offline on different devices, and whenever I come online, it all syncs up. No issues.

It does not give me p2p topology. Is that what you mean?


Hi Kevin, author here, are you sure we are on the same page about what I'm saying in this article?

For example, the debugging section is NOT about debugging problems inside Yjs, it's about debugging one's own bugs while one is using something like Yjs or prosemirror-collab. I'm normally a happy gambler but I actually think the Yjs GC algorithm probably does do what it says... indeed, my complaint is that I specifically do not want that behavior. :)

Likewise, the point I'm making about performance is NOT that Yjs is "slow". I'm saying that it's empirically very challenging to meet the 16ms perf budget even in the simplest possible realistic collab scenario... and that because of this, it is (1) very unappealing and (2) in our experience, challenging to attempt to do this when you also have to do a pile of extra things that are unrelated to the task at hand, like translate `Transaction` to and from operations on an XML doc, and deal with all the consequences of messed up positions passed to plugins. I do understand you have your own benchmarks that give you the confidence to (without qualifications) claim that y-prosemirror "runs at 60fps". You really are not curious about why we think that's not the case?

If we can't get to a shared understand what is being said here, it's going to be very hard to talk about it at all. And on the two material points at stack in your response, I believe you have the precise opposite understanding of what was written. I'm happy to keep discussing but it feels like we're starting from scratch after this response, again.


So, we are basically making two points.

First, the fact that Yjs bindings, by design (for ~6 years), replace the entire document, does in my opinion, indicate a fundamental misunderstand what rich text editors need to perform well in any circumstance, not just collaborative ones. As I say in the article... I hope to be able to write another article that this has changed and they now "get" it, but for now I do not think it is appropriate to trust Yjs with this task for production-grade editors. I'm sorry to write this, but I do think it's true! I'm not trying to bag on anyone!

Second, and more material: to deploy Yjs to production in the centralized case, I think you are very much swimming against the current of its architecture. Just one example is permissions. There is no established way to determine which peers in a truly-p2p architecture have permissions to add comments vs edit, so you will end up using a centralized server for that. But that's not free, CRDTs are mechanically much more complicated! For example, you have to figure out how to disallow a user to make mark-only edits if they have "commenter" access, but allow editing the whole doc for "editor" access. This is trivial in `prosemirror-collab` (say) but it's very hard in Yjs because you have to map it "through" their XML transformations model.

I'm happy to talk more about this if it's helpful. But yes, we are trying to say some stuff about Yjs specifically, and some stuff about CRDTs generally.


You misunderstand how the "document replacement" in y-prosemirror works. It's like arguing that React is bad because it performs a complete document replacement on every change. The diffing part makes it fast.

That said, it's not without problems - I acknowledge that. But it's not as bad as you make it sound. You didn't list one concrete case when you had issues with it.

I'm very happy that Nick and I finally found funding to make a rewrite happen. It really did take 6 years to make this happen, because it's hard to find funding for open source projects.


Just tying up loose ends here, in this other comment I suggest that Kevin and I are not on the same page about the point I was making in the article: https://news.ycombinator.com/item?id=47422455

I will additionally note that I'm not making any point about performance in this comment either, though. "Perform" in this context is not about 60fps, it's about whether, like, plugins work.


FWIW, I'm literally working on rewriting the y-prosemirror binding today with Kevin Jahns, the creator of Y.js and wrote the initial binding. Yes, the current binding has it's flaws, but we hope to flush out the most egregious of them with a completely different design which I made a presentation about at FOSDEM this year: https://fosdem.org/2026/schedule/event/8VKQXR-blocknote-yjs-...


Thanks Nick. I am aware. The blog post directly links to the PR you merged some days ago that (as I understand it) kicks off the effort. I also mention specifically I know you're working on it.

https://github.com/disarticulate/y-webrtc/blob/master/src/y-... has a validMessage function passed into the room. This allows you to validate any update and reject them. It might be "costly", but it lets you inspect the next object. Since Yjs doesn't care about order or operations, it doesn't really matter how long validation takes.

Not sure what the error conditions loop like, but you could probably bootstrap message hashes in a metadata array in the object, along with encryption signatures to prevent unwanted updates to objects.


I know it seems that way, but it's actually not 80% of the way to a CRDT because rich text CRDTs are an open research problem. Yjs instead models the document as an XML tree and then attempts to recreate the underlying rich text transaction. This is much, much harder than it looks, and it's inherently lossy, and this fundamental impedance mismatch is one of the core complaints of this article. Some progress is being made on rich text CRDTS, e.g., Peritext[1]. But that only happened a few years ago.

Another important thing is that CRDTs by themselves cannot give you a causal ordering (by which I mean this[2]), because definitionally causal ordering requires a central authority. Funnily enough, the `prosemirror-collab` and `prosemirror-collab-commit` do give you this, because they depend on an authority with a monotonically increasing clock. They also also are MUCH better at representing the user intent, because they express the entirety of the rich text transaction model. This is very emphatically NOT the case with CRDTs, which have to pipe your transaction model through something vastly weaker and less expressive (XML transforms), and force you to completely reconstruct the `Transaction` from scratch.

Lastly for the algorithm you propose... that is, sort of what `prosemirror-collab-commit` is doing.

[1]: https://www.inkandswitch.com/peritext/

[2]: https://www.scattered-thoughts.net/writing/causal-ordering/


It might fix the replace-everything bug. It definitely does not fix any of the other issues I mentioned. Even just taking the permissions problem: Yjs is built for a truly p2p topology you as a baseline will have a very hard time establishign which peers are and aren't allowed to make which edits. You can adopt a central server, but then the machinery that makes Yjs amenable to p2p is uselessly complicated. And if you cross that bridge, you'll still have to figure out how to let some clients do mark-only edits to the document for things like comments, while other can edit the whole text. That can be done but it's not at all straightforward, because position mapping is very complicated in the Yjs world.


Hi Matt! Good to see you here. For those who don't know, Matt also wrote a blog about how to do ProseMirror sync without CRDTs or OT here: https://mattweidner.com/2025/05/21/text-without-crdts.html and I will say I mostly cosign everything here. Our solution is not 100% overlap with theirs, but if it had existed when we started we might not have gone down this road at all.


Your part 1 post was one of the inspirations for that :)

Specifically, it inspired the question: how can one let programmers customize the way edits are processed, to avoid e.g. the "colour" -> "u" anomaly*, without violating CRDT/OTs' strict algebraic requirements? To which the answer is: find a way to get rid of those requirements.

*This is not just common behavior, but also features in a formal specification [1] of how collaborative text-editing algorithms should behave! "[The current text] contains exactly the [characters] that have been inserted, but not deleted."

[1] http://www.cs.ox.ac.uk/people/hongseok.yang/paper/podc16-ful...


Author here. I'll actually defend this. Most of the subtlety of this part is actually in document schema version mismatches, and you'd handle that at client connect, generally, since we want the server to dictate the schema version you're using.

In general, the client implementation of collab is pretty simple. Nearly all of the subtlety lies in the server. But it, too, is generally not a lot of code, see for example the author's implementation: https://github.com/ProseMirror/website/tree/master/src/colla...


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

Search: