I think most people would love to the know the 'why'. This page discusses differences with prosemirror and is the closest I got to that question: (https://wordgard.net/docs/prosemirror/).
One thing to note is that there is not an upgrade path. Many concepts are shared with prosemirror, but it seems that switching means doing quite some work (correct me if I am wrong). Obsidian is based on Code Mirror so I guess they won't be switching, but tiptap.dev and others do.
@merijn, maybe you could address why wordgard is worth the switching cost?
It may not be. If you're happy with ProseMirror, continue to use ProseMirror. I have your back.
But as the blog posts describes, I had a whole pile of new design insights that avoid some of the issues I've ran into with ProseMirror, so I had the itch to build a new iteration.
I'll add a link to the blog post to the docs section of the website.
I'm part of the Zoho Writer team (Google docs alternative). And the new architecture is very similar to Zoho Writer i.e edits represented as a sequence of retains/keeps followed by action.
Also the decision to forego browser's selection and draw a custom layer.
All this makes reasoning about changes a lot more saner and intuitive. I've always wondered why prosemirror's transactions & steps couldn't be simplified further so I'm one vote up for the new design direction!
Wikipedia is intriguingly inconsistent - claims that Marijn is the Dutch variant of Marinus meaning 'marine' like Marius, Mario etc. but other pages claim Marius is more likely to be from 'mars' or 'male' than 'marine'.
I always wondered why there is no code/package overlap between CodeMirror and ProseMirror (or now Wordgard). Have you tried this? Were there particular blockers?
There's a significant amount of code in Wordgard that is copy-pasted from CodeMirror or ProseMirror, but modified enough that trying to share it would involve nightmarish amounts of type parameters and extra indirection. You could certainly build a generic editor framework and then build several editors on top of it, but you'd end up with Raku-level amounts of architecture acrobatics and extra complexity, much of which would leak out in the public library interface, and I don't think that is generally worth it. I do occasionally, when I realize a bug fix applies to one of my other projects as well, repeat it there. But that's okay.
"Why is it worth the switching cost?" is the genuine question I have too. Or more importantly, why not just make it ProseMirror v2?
The landing page needs more information about the "why" rather than the "what".
> A ProseMirror 2.0 with an incompatible interface would amount to the same but make it ambiguous what people mean when referring to ProseMirror. Trying to graft stuff on in a backwards-compatible way as an 1.x version would produce a compromised win32-style mess.
One thing i've struggled with with Prosemirror (via TipTap) is that I very often need to interact with JSON representation of the document programmatically to extract data from it, this means I need (okay, strongly prefer) a statically-typed representation of it.
Prosemirror doesn't really have any mechanism to do this, so i've ended up doing one of these two things:
1. Define the schema twice, once using Prosemirror and once using something like Zod. Then having a battery of equivalence tests to assert that the schemas match.
2. Build a meta schema definition layer that can output a Prosemirror schema, but conforms to the standard schema spec (https://standardschema.dev/), this approach is more viable if not using something like Tiptap.
I haven't tried using Wordgard yet, so I can't tell if it does anything to address this, but just calling it out as a pain point i'd love to see solved.
This is amusing as well as slightly scary. Prosemirror over the years has become the backbone of editors on the web. ChatGPT uses it. Gemini uses it. Linked chat and feed composers are Prosemirror powered. Literally every serious product uses Prosemirror for composing text on the web.
There is an entire YC company built on top of Prosemirror (Tiptap).
The thought that Prosemirror is no more in active development is scary.
> The thought that Prosemirror is no more in active development is scary.
Which is a thing that I never said. In fact I went out of my way in all the announcements to stress that ProseMirror maintenance is continuing as it has been.
The only scary thought is that all these important operations don't have a plan B if prosemirror, a software they don't write, don't own and presumably don't pay, goes away.
Also MIT-licensed software doesn't 'go away' all that easily. If a piano fell on my head tomorrow, interested parties would probably manage to continue development in a fork.
There is contenteditable, which is what all these (Wordgard, ProseMirror) are fundamentally built on. The rest is just the UI, and interop with systems that don't desire arbitrary HTML as input.
While these use contenteditable, it's not accurate to say they're just contenteditable plus some UI and interop.
None of these modern editors (Wordgard, ProseMirror, Lexical, Slate) use contenteditable for the document model. Rather, they have their own internal document model and use contenteditable as a kind of input layer where the editor monitors what the browser does, then translates that into actual edits.
Early editors like FCKEditor and TinyMCE were only wrappers around contenteditable. They used the DOM as the real document model, then intercepted certain keypresses and events and "fixed" the behavior when it wasn't correct (e.g. double enter inside a bullet list should switch to paragraph mode).
The result was rife with bugs and inconsistencies, and didn't allow for a proper split between the model and the view (e.g. to represent columns, video embeds, and so on).
I’m not a historian but I think FCKEditor and TinyMCE predated contenteditable. These were solutions wrapping textarea back in the day if my memory serves me.
~6 years ago had a very hard time researching and implementing an @-style remote resource completion (other users and documents to reference) and the style of extensions in this editor seem very much like an evolution of prosemirror.
I'd really appreciate it this was something built in, not something I have to build based on the dinosaurs example. Every time I need to reach for one of these text editor libraries that is my no. 1 usecase, followed by WYSIWYG.
First-class mobile support should be there (though there will be bugs, given that this hasn't seen much real-world testing yet — report them if you see them).
I haven't entirely decided what utilities I'm going to include in the core library, but mentions are definitely on the list for potential inclusion.
The person who got inspired by prosemirror and built lexical is no more at meta. Go to the repository and you'll find it's already in maintenance mode. Its promise of cross platform extensible editor is unrealised yet.
I've personally been hoping for something like this for a while now. Especially a toolset that is not just targeting yet another SaaS or LLM or social media clone interface.
I don't know if you ever used Draft.js that FB put out some time ago, but it was a horribly buggy monstrosity that was a heavy lift to move away from. One could not write several paragraphs and edit them without losing a lot of work. I wouldn't touch "Lexical" no matter the marketing they put on top. I wouldn't be half as critical if it wasn't one of the wealthiest companies on the planet known for injecting billions into black holes while they raid every area of your life they possibly can for data to be used to manipulate socio-political matters everywhere. If they're going to do that, and release open source libraries, then at least make them good enough to be seductive. They aren't.
ProseMirror and seemingly WordGard have real thought and care put into them by people who have long made the DOM/developer experience and the writing experience priorities– not just their "mind share" for whatever dark purposes drive companies like Meta.
ProseMirror is an excellent project, but it’s always been a bit awkward using it directly in React. I remember that NYT had to rewrite the renderer to make it work for their use-case.
I am not sure if this makes things easier for react interop, but this piece might be of interest too:
> One of the biggest mistake blunders in ProseMirror is that the editor view does not get access to the transaction objects when updating, just the state. Wordgard does not repeat this mistake, and makes updates take transactions, not just a new state.
> This means that things like the DOM update logic and UI plugins can precisely observe what happened, and handle changes in a efficient and more effective way. The weird unexpected DOM redraws that are still a thing in ProseMirror should not occur. Only the precise DOM structure affected by the new transactions will be updated.
Anyways, it is great to see Merijn still going strong with his free work. Anyone needing interactive rich text on the web won't find anything better than his brain childs.
I don't like WYSIWYG on the web. You do a long and tedious formatting of a forum post, then close the tab and it's all gone. I prefer to use a local text editor then Ctrl+V into web form. Which I can with markdown
I've seen this solved in some platforms with localstorage, so that it automatically saves your "draft" as you type and seamlessly restores it if you re-open the page. It was a really nice surprise the first time I experienced it (after closing a tab by mistake).
Check out Linear, I'm not affiliated, just yesterday I happened to close the dialog by misclicking and when I pressed create issue again there was the wall of text I wrote. My point is it's not a technical problem but a product one.
It depends for me. For my blog I have a web based editor, but one, that is just plain markdown with a preview. Similar to your described workflow.
For a note taking app I decided to use WYSIWYG because I don't have the space for a split view and didn't want to just look at the markdown as is.
My main gripe with WYSIWYG is that they can get in your way. When I create a verbatim block and can't leave that block anymore (looking at you Teams). I guess thats also why I enjoyed LaTeX as much as I did.
I've had another report like this (they claimed it had been down for days). But I haven't noticed anything wrong with it (and I'm using it a lot). What did 'down' look like?
Also, though GitHub's lack of reliability was part of the motivation to self-host, it was only a minor factor. The way they are trying to make Copilot a thing, at the cost of everything else, the way they handle US sanctions by blocking everybody from entire countries, and the way the web interface feels ever more heavyweight and sloppy were also factors.
I can’t believe that we are still trying to solve this. One would think that after so many years (I’ve started doing web almost 20 years ago) we would end up with some solutions baked in browsers
I think the issue is not the "solving", rather that people have different opinions and they want different things, and there isn't common agreement what is needed or how. Most editors work just fine for the basic needs. But well, that is my opinion.
The design and aesthetics of the page are really impressive, but what caught my attention was the "Deluxe API" which was new to me because I hadn't heard of it before.
One thing to note is that there is not an upgrade path. Many concepts are shared with prosemirror, but it seems that switching means doing quite some work (correct me if I am wrong). Obsidian is based on Code Mirror so I guess they won't be switching, but tiptap.dev and others do.
@merijn, maybe you could address why wordgard is worth the switching cost?
EDIT: I see many points are addressed in Merijns personal blog. I submitted (https://marijnhaverbeke.nl/blog/wordgard-0.1.html) to HN for better context.
It may not be. If you're happy with ProseMirror, continue to use ProseMirror. I have your back.
But as the blog posts describes, I had a whole pile of new design insights that avoid some of the issues I've ran into with ProseMirror, so I had the itch to build a new iteration.
I'll add a link to the blog post to the docs section of the website.
(It's marijn, not merijn.)
Also the decision to forego browser's selection and draw a custom layer.
All this makes reasoning about changes a lot more saner and intuitive. I've always wondered why prosemirror's transactions & steps couldn't be simplified further so I'm one vote up for the new design direction!
Wikipedia is intriguingly inconsistent - claims that Marijn is the Dutch variant of Marinus meaning 'marine' like Marius, Mario etc. but other pages claim Marius is more likely to be from 'mars' or 'male' than 'marine'.
> I'm not all that fond of the ProseMirror pun anymore either (it's CodeMirror but for prose, get it?)
So... It's time for someone to create Codegard, i guess?
> A ProseMirror 2.0 with an incompatible interface would amount to the same but make it ambiguous what people mean when referring to ProseMirror. Trying to graft stuff on in a backwards-compatible way as an 1.x version would produce a compromised win32-style mess.
Prosemirror doesn't really have any mechanism to do this, so i've ended up doing one of these two things:
1. Define the schema twice, once using Prosemirror and once using something like Zod. Then having a battery of equivalence tests to assert that the schemas match. 2. Build a meta schema definition layer that can output a Prosemirror schema, but conforms to the standard schema spec (https://standardschema.dev/), this approach is more viable if not using something like Tiptap.
I haven't tried using Wordgard yet, so I can't tell if it does anything to address this, but just calling it out as a pain point i'd love to see solved.
There is an entire YC company built on top of Prosemirror (Tiptap).
The thought that Prosemirror is no more in active development is scary.
From their blog: "I'm still proud of ProseMirror, and ProseMirror isn't going anywhere—it will continue to be maintained."
Which is a thing that I never said. In fact I went out of my way in all the announcements to stress that ProseMirror maintenance is continuing as it has been.
Also MIT-licensed software doesn't 'go away' all that easily. If a piano fell on my head tomorrow, interested parties would probably manage to continue development in a fork.
but as @john_strinlai as I have said it doesn't seem like Prosemirror is going unmaintained. It will continue to be maintained
but I think its worth thinking about the structure of the whole thing being so similar to the xkcd which is what might be the scary part of it.
It is insane that there isn't a web standard implementation for this passed 15 years ago.
None of these modern editors (Wordgard, ProseMirror, Lexical, Slate) use contenteditable for the document model. Rather, they have their own internal document model and use contenteditable as a kind of input layer where the editor monitors what the browser does, then translates that into actual edits.
Early editors like FCKEditor and TinyMCE were only wrappers around contenteditable. They used the DOM as the real document model, then intercepted certain keypresses and events and "fixed" the behavior when it wasn't correct (e.g. double enter inside a bullet list should switch to paragraph mode).
The result was rife with bugs and inconsistencies, and didn't allow for a proper split between the model and the view (e.g. to represent columns, video embeds, and so on).
I was searching for something like this recently but ended up rolling my own using a block-based OT to local server and diff sync to remote ones.
I’m reading the system guide and nodding along. It’s super validating to see the similarities and contrasts.
I'd really appreciate it this was something built in, not something I have to build based on the dinosaurs example. Every time I need to reach for one of these text editor libraries that is my no. 1 usecase, followed by WYSIWYG.
As would first class mobile support.
I haven't entirely decided what utilities I'm going to include in the core library, but mentions are definitely on the list for potential inclusion.
I'd pick prosemirror any day over Lexical.
But Claude is playing part of it.
https://github.com/facebook/lexical
I'll save you the trouble, you will not find one.
I've personally been hoping for something like this for a while now. Especially a toolset that is not just targeting yet another SaaS or LLM or social media clone interface.
I don't know if you ever used Draft.js that FB put out some time ago, but it was a horribly buggy monstrosity that was a heavy lift to move away from. One could not write several paragraphs and edit them without losing a lot of work. I wouldn't touch "Lexical" no matter the marketing they put on top. I wouldn't be half as critical if it wasn't one of the wealthiest companies on the planet known for injecting billions into black holes while they raid every area of your life they possibly can for data to be used to manipulate socio-political matters everywhere. If they're going to do that, and release open source libraries, then at least make them good enough to be seductive. They aren't.
ProseMirror and seemingly WordGard have real thought and care put into them by people who have long made the DOM/developer experience and the writing experience priorities– not just their "mind share" for whatever dark purposes drive companies like Meta.
I wonder how Wordgard compares in this aspect!
I am not sure if this makes things easier for react interop, but this piece might be of interest too:
Anyways, it is great to see Merijn still going strong with his free work. Anyone needing interactive rich text on the web won't find anything better than his brain childs.They are also working on a collaborative editing suite for ProseMirror as an alternative to TipTap https://pitter-patter.dev/
My main gripe with WYSIWYG is that they can get in your way. When I create a verbatim block and can't leave that block anymore (looking at you Teams). I guess thats also why I enjoyed LaTeX as much as I did.
https://code.haverbeke.berlin/wordgard/wordgard/src/branch/m...
If the motivation for moving off GitHub was "GH is down too much", it might be worth tracking how many 9's of uptime is lost in the self-hosted case.
Also, though GitHub's lack of reliability was part of the motivation to self-host, it was only a minor factor. The way they are trying to make Copilot a thing, at the cost of everything else, the way they handle US sanctions by blocking everybody from entire countries, and the way the web interface feels ever more heavyweight and sloppy were also factors.
Maybe something changed in the meantime, but I'm seeing what appears to be the code for it here: https://code.haverbeke.berlin/wordgard/wordgard/src/branch/m...
Android Chrome.
I wanted to clear the text box, so I marked the entire text and hit backspace. It only removes the last letter.
So then I marked the entire text and pressed a letter. That successfully replaced all the text with the one letter.
But then the editor broke completely. I cannot put newlines anymore, backspace is inconsistent, and the text cursor isn't shown.
(The editor breaking after marking all the text and pressing a letter is reproducible.)
At least on mobile the editor seems to still be unstable.