HNHacker News
TopNewBestAskShowJobs

antics

4,119 karma · joined August 13, 2010

clemmer.alexander@gmail.com alex@moment.dev
submissionscomments
antics··on Olo (Color)
If you are interested in "imaginary" colors, the gamut is actually well-specified, and (I hope it is appropriate to comment) that I made a visualization where you can drag a selection thumb over the gamut to see the "simulated" version of that color. Also include it is a 12-step contrast-sensitive color palette generator for said imaginary colors, which would allow you to make websites and (say) vscode themes using entirely imaginary colors! https://docs.moment.dev/d/hausdorff/2zmqjlmldchela29xvbzlbki...
antics··on Incident March 30th, 2026 – Accidental CDN Caching
So on the one hand you have a direct statement from the source that the cause of this incident is humans. On the other hand, while we all agree there is no specific evidence that AI caused the issue, the guy who made that statement, like, really loves AI.

In my life I have gone back and forth on the idea that 12 angry men is a kind of facile representation of how people think and what kinds of evidence really form the basis of a reasonable society. This comment section is doing a really good job of stretching my resolve to believe we are getting at least better.

antics··on Incident March 30th, 2026 – Accidental CDN Caching
> 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.

antics··on Incident March 30th, 2026 – Accidental CDN Caching
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.

antics··on Return of the Obra Dinn: spherical mapped dithering for a 1bpp first-person game
> 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!

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
lol ok we can talk and record it. I want to make it clear that this is NOT a debate, though. I actually want to be convinced!
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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?

antics··on We're building a better rich text editing toolkit
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.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
The magic of CRDTs does not prevent this. They are in exactly the same boat as OT, prosemirror-collab and prosemirror-collab-commit. It can't be prevented. The problem is worse with CRDTs because they instantly destroy user intent in the conversion to/from their underlying representation, which is the XML document. See discussion with Marijn about, e.g., splitting blocks above.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
I do not know how to say this another way. No. Nothing in this article was created, edited, outlined, pre-drafted, suggested, or in any other way influenced by AI. AI did not write the words, it did not review the words, it was not a part of a pre-writing discussion that influenced the words. There is NO AI IN THIS ARTICLE OR AS AN INPUT TO THIS ARTICLE. If the article is an apple, then 0% of the apple is AI or AI influenced.

And let this be a lesson to you. You apparently do not have any ability to distinguish between these two kinds of thing.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Actually, I think I agree with most of this... except the part where you think it's not clear-cut, ha ha. I meant that not as a comparison between OT and CRDTs, but as a comparison to prosemirror-collab. My opinion is that in the centralized server case, it is (unfortunately) basically better in every dimension.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Ok Marijn I understand. I'm sorry I caused you an inconvenience. Of course, I know that implementing server-side prosemirror-collab is not entirely without problems (since we have done it) and take your point, which is correct. If I was to do this again I'd find a different way to say this than "40 lines of code."

With that said... I do not agree it is not "simple." Or at least, I think it is about as simple as it can possibly be.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Just to be extremely clear: we pay for a lot of OSS software. We pay one individual project more than $10,000 a year. We would have paid for Yjs too, if we thought it was a good use of resources!
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Hi Joseph! Good to see you here.

Sorry, I see why this was confusing. What I'm saying is that because users perceive the results of OT, CRDTs, prosemirror-collab, etc. as data corruption, they require presence carets as a UI affordance, to steer them away from direct edit conflicts.

If you can't have presence carets, yes... likely best to have a diff view. And in our case, we use git/jj for this, rather than CRDTs.

For the "history of" stuff... in spite of the fact that we have our disagreements, I actually think it would be very nice to have Kevin and everyone else on the record long-form talking about this. Just because I am a non-believer doesn't mean it wasn't worth trying!

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use 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.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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/

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
To be clear, we ARE arguing CRDTs needlessly complex for the centralized server use case. What I am describing in the "delete and replace all on every keystroke" problem is the point at which it became clear to me that the project did not understand what modern text editors need to perform well in any circumstance, let alone a collab one.

I think this is still reasonable to say because the final paragraph in that section is 100% about how they might fix the delete-all problem, and I hope they do, so that I can write about that, too. But also, that the rest of the article is going to be about how you have to swim upstream against their architecture to accomplish things that are either table stakes or trivial in other solutions.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
First of all, thanks for chiming in! I wish someone would collect stuff like this and write it down in some sort of "oral history of collab editing."

Second of all, I actually think we're more aligned than it seems here. What we're really advocating for is being super clear about what your end-user goals are, and deriving technology decisions from them, instead of the reverse. Our goals for this technology are (1) users should be able to predict what happens to their data, (2) the editor always run at 60fps, and (3) we are reasonably tolerant of transient periods of disconnection (up to, say, 30s-1m).

Because of (1) in particular, a lot of our evaluation was focused on understanding which situations users would be unable to predict what was going to happen to their data. This is only our own experience, but what we found (and the impetus for part 1 of this series) is that almost 100% of the time, when there is a direct editing conflict, users interpret the results of the dominant CRDT and OT implementations as silently corrupting their data. So, the name of the game is to decrease the likelihood of direct editing conflicts, e.g. presence carets in the live-collab case. In particular, we did not notice a meaningful difference between how users view reconciliations of OT and CRDT implementations.

Since our users could not tell the difference, and in fact viewed all options as equally bad ("disastrous" as one user said), this freed us up to consider a much broader class of algorithms, including prosemirror-collab and prosemirror-collab-commit.

I know there is a rich history of why OT is OT, but our final determination was made pretty simple by the fact that the source of the majority of race conditions in our view come from the difficulty of integrating CRDTs and OT directly into modern editing stacks, like ProseMirror. As far as I am aware, prosemirror-collab-commit behaves as good or better on every dimension than, say, an OTTypes implementation would... and mostly that is because it is native to the expressive `Transaction` model of the modern editor. If we had to do interop I think we would have shipped something noticably worse, and much slower.

If you have a different experience I would love to hear about it, as we are perennially in the market for new ideas here.

antics·
Author here, just chiming in to say that Matt has an actual PhD on the subject so rather than explain it worse, I will just let him say the probably-actually-correct thing here.
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Great question. Matt has a comment about this here, and he has an actual PhD on the subject! So rather than doing a worse job explaining I will leave it to him to explain: https://news.ycombinator.com/user?id=mweidner
antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
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...

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
This is great feedback, thank you. I will say that IS our goal... but we only really launched last week and are still figuring out what resonates with people and what they really want! It sounds like you're saying that the organization aspects are not there, which is very helpful to know... I am not quite sure I understand if you also think the toolbuilding is lacking?

If you are open to it, I'd love the opportunity to hear more. Here or email (alex@moment.dev) or our Discord (bottom right of our website) or Twitter/X... or whatever you prefer.

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
Author here. I think it depends what you're doing! OT is a true distributed systems algorithm and to my knowledge there are no projects that implement true, distributed OT with strong support for modern rich text editor SDKs like ProseMirror. ShareJS, for example, is abandoned, and predates most modern editors.

If you are using a centralized server and ProseMirror, there are several OT and pseudo-OT implementations. Most popularly, there is prosemirror-collab[4], which is basically "OT without the stuff you don't need with an authoritative source for documents." Practically speaking that means "OT without T", but because it does not transform the ops to be order-independent, it has an extra step on conflict where the user has to rebase changes and re-submit. This is can cause minor edit starvation of less-connected clients. prosemirror-collab-commit[5] fixes this by performing the rebasing on the server... so it's still "OT without the T", but also with an authoritative conflict resolution pseudo-T at the end. I personally recommend prosemirror-collab-commit, it's what we use, and it's extremely fast and predictable.

If you just want something pedogocically helpful, the blessed upstream collaborative editing solution for CodeMirror is OT. See author's blog post[1], the @codemirror/collab package[2], and the live demo[3]. In general this implementation is quite good and worth reading if you are interested in this kind of thing. ShareJS and OTTypes are both very readable and very good, although we found them very challenging to adopt in a real-world ProseMirror-based editor.

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

[2]: https://codemirror.net/docs/ref/#collab

[3]: https://codemirror.net/examples/collab/

[4]: https://github.com/ProseMirror/prosemirror-collab

[5]: https://github.com/stepwisehq/prosemirror-collab-commit

antics··on Lies I was told about collaborative editing, Part 2: Why we don't use Yjs
I'm not sure I fully understand, but to be clear, we actually do voluntarily pay for the Free and OSS software we use. For example, we support `react-prosemirror` directly with monetary compensation. And if we used Yjs, we would have paid for that too. So in that sense, I do think of us as customers!

It's hard to tell, but I think you also might be saying that criticizing the FOSS foundations of our product actually hurts the ecosystem. I actually am very open to that, and it's why we took so much time writing it since part 1 came out. But the Yjs-alternative technology we use is all also F/OSS, and we also do directly support it, with actual money from our actual bank account. All I'm recommending here is that others do the same. Sorry if that was not clear.

The rest of your reply, I'm not sure I grok. I think you might be suggesting that we are sock-puppeting `auggierose` or `skeptrune`, and that we are part of some (as you put it) "cult" of the Bay area! Let me be clear that neither of these things true. I don't know anyone at Mintlify personally, and in any event we are from Seattle not the Bay!

Page 1 of 15Next →