Hacker News new | past | comments | ask | show | jobs | submit login
Slate – A completely customizable framework for building rich text editors (github.com/ianstormtaylor)
164 points by corentin88 on July 29, 2021 | hide | past | favorite | 49 comments



Word of warning, their readme says 'Some of its APIs are not "finalized" and will have breaking changes over time as we discover better solutions.'

I started using this library several years ago and have eventually had to rework it using prosemirror because I just couldn't keep up with the breaking changes.

Both libraries work in very similar ways, with slate using React for its rendering layer. However Prosemirror has been v1 for quite a while and in retrospect I'd have saved myself a lot of headaches if I'd taken the above warning more seriously.


Same experience here. They changed APIs with no warning at version 0.46, breaking whatever spotty iOS/Android support they had. That’s not a knock against them: mobile contentEditable is terribly difficult to get right. But the surprise total deprecation of their stable branch was uncool to say the least, even if they did warn the software was beta. I heard Slate raised money to fix Android support, but whether or not that’s true, the whole thing was a really bad experience.

I also wholeheartedly recommend ProseMirror. It’s a bit complicated in some ways, but it works across platforms, is used in production widely at big companies despite sort of flying under the radar, and has been stable for years. If you’re looking for a fully baked React integration, TipTap[0] seems really nice, or if something minimalist then a plug for my own integration: use-prosemirror[1].

[0] https://www.tiptap.dev

[1] https://github.com/dminkovsky/use-prosemirror


Never seen tiptip before, looks pretty slick.

At work we need only the most basic customization (some inline spans for template vars) and we've cobbled together a Draft.JS implementation that's pretty buggy and has random runtime errors (unhandled nulls internal to the Draft.JS code).


Yes, I looked at TipTap for a while recently and the API looks like a really nice layer on top of ProseMirror.

Draft.js was another far out experience for me. I built the first attempt at my app with it, only to discover that Draft.js didn't work on Android. It was buggy on iOS, but on Android just didn't work. If you've been using Draft.js you probably remember Android support landing with the huge PR from Fabio M. Costa at GoDaddy[0], but by then I had already decided I needed to find something else. That PR actually led me to ProseMirror:

> This approach is the one used by Prosemirror (see https://github.com/ProseMirror/prosemirror-view/blob/master/...), which is the only Rich Text Editor I've tried that works well on Android. [1]

When I looked at ProseMirror, I was spooked by the apparent complexity. Tried Quill, Trix (worked great, but uncustomizable) and then went with Slate, only to have the above-mentioned experience. Remembered that comment on the PR, and redid my editor in ProseMirror, which finally was something that worked. Thank you Marijn and the ProseMirror community. It's been a journey with these editors.

[0] https://github.com/facebook/draft-js/pull/2035

[1] https://github.com/facebook/draft-js/pull/2035#issue-2613622...


Same, I switched after a long stretch in 2020 where Slate bug fix PRs stagnated. I find the ProseMirror API less intuitive but overall it has fewer bugs and I have been able to customize it pretty heavily.


I had a similar experience. On a project I'm working we had to support IE11. Slate docs mentioned that it doesn't fully support IE11 out of the box, but that support can be achieved using polyfills. This turned out to be false and that part of documentation was very old and inaccurate unfortunately.

After few weeks of development we ran into IE11 issues we couldn't fix and Slate devs expressed that they are not at all interested in supporting IE11 in any way, which is a fair point of course since IE11 is on its way out and supporting it is a big chore. There were some PRs that were supposed to address some of the issues, but development is kinda all over the place on Slate so we weren't confident enough to go with it and decided to switch to ProseMirror.

It hasn't been easy and ProseMirror can be complicated, but we managed to work it out and created what we needed.


This has been my experience with Slate few years ago. The breaking changes were too frequent to stay productive and the project needed more baby sitting than we'd have liked.


Have been building https://saga.so with Slate for the last 12 months.

Can confirm it was a bumpy ride, but it also gave back a lot. The main reasons for using Slate over Prosemirror were the almost complete API for managing and editing a block based page, and the fact that it's written in Typescript (although partial types support is a recent addition).

We still have quite a few Slate-related bugs, and the size of our extension code to cover for slate bugs/omissions or to extend the behavior in general is now many thousands of lines long, but wouldn't have chosen anything else.

We tried Prosemirror at the beginning and it was very hard to get into. We checked again when TipTap came out (which is a wrapper of Prosemirror), but all our advanced custom logics would have had to be rewritten in Prosemirror so we abandoned the idea very easily. But we support the team behind Tiptap on another open source project, Hocuspocus, which is a client/server wrapper for Yjs, a library for collaboration with a focus on text editors.

In the end, I have PTSD from Slate, but also, we couldn't have done it without it, so thanks Ian if you're reading this!

https://tiptap.dev

https://hocuspocus.dev

https://yjs.dev

* my first comment on HN after years of lurking!


> and the size of our extension code to cover for slate bugs/omissions or to extend the behavior in general is now many thousands of lines long

yikes, but if it's working now then just tech debt for the future.

I initially investigated using slate.js, prosemirror, and draft.js for my project https://sqwok.im but ended up writing my own parser instead, learning quite a bit about such fun api's as browser Range(), and the many pitfalls of cross-browser compatibility. It was laborious but got it to a place I'm happy with.

Congrats on Saga! It looks like something I might use and I dig the UI.


I know it sounds like tech debt...and it is. But we're to a point where we could potentially be able to integrate those extensions back into the core library and our slate-saga, so it's eventually paying back.

We really needed extensive text manipulation, so starting from Slate gave us a considerable initial boost, but congrats on building your own parser!

Congrats to you and if you try out Saga, let us know about it :)


Curious if you looked into Editor.js at all when building?

Im in the middle of sizing up text editors myself, seems like editor.js would require less work, but wondering if I’m missing any red flags and should go with Slate or tiptap (prosemirror) instead.

At some point down the road I’d love to implement collaborative editing.


We did look into editor.js and the API seems not as advanced as Slate's, mostly because Slate tries to replicate the DOM's behavior with Nodes and Ranges, so you can make edits in a very fine grained way.

If you're going for a new text editor, I'd start with Tiptap and try to check how to do advanced custom stuff with Prosemirror. Maybe if Tiptap 2 was out a year ago, we would have started with that.

For collaborative editing, definitely check out https://yjs.dev


Very cool project. Thanks for sharing.


The recent changes to the API in 0.50 look good. The number of iteration passes really shows. Out of the available open source editor frameworks, Slate is probably most similar to Notion’s internal editor system. If I had to rebuild on a framework tomorrow, it’d be Slate or ProseMirror. Still if I used Slate it would be with the expectation that I’d end up owning an aging fork of a forgotten version at some point.


I've been using Slate heavily this year. I'm not a Slate developer, but I've read a lot of the source code, follow all the Github issues, etc., and I'm "owning an aging fork". As far as I can tell, the API instability mentioned elsehwere in this thread resulted from a nearly complete rewrite (inspired by immerjs) that launched in May 2020; for over a year since then, the API has been very stable, mainly because Ian Taylor, who wrote most of Slate, seems to have moved on to other projects (see https://github.com/ianstormtaylor/slate/graphs/contributors)... there's still a lot of work on Slate, but it's mainly by other people who are trying to preserve the vision that Ian laid out. I ended up forking only the React part of Slate, which is officially a plugin, and massively rewriting it to support virtualized windowing, so we can work with very large possibly complicated to render documents. I also added fairly generic realtime collaboration support. This is currently used in https://cocalc.com for WYSIWYG editing of Markdown documents. I also have plans to extend my use of Slate with windowing to Jupyter notebooks and other document types.

I chose Slate over Prosemirror because the source code of Slate is Typescript written in a clear modern style, and I was able to start reading any part of it and understand it easily, whereas I find Prosemirror's core source code more difficult (this may just be a reflection of my shortcomings). I spent a lot of time initially just reading Slate PR's claiming to fix bugs, then integrating the PR's into my fork, often in a way that makes sense for my project, but likely wouldn't in general (I left helpful remarks on Github).

Slate is an interesting project, and it is comparable to Prosemirror. However, development is structured very differently at present, and I think there's little funding behind Slate, whereas the author of Prosemirror seems to have done a good job encouraging sustainable donations. I think Ian Taylor, who mainly wrote Slate, also cofounded a company called Segment.io, which is a serious startup that was recently sold to Twilio, so I don't know what his motivations are.

I have no plans to switch from Slate to Prosemirror. Getting virtualized windowing to work with Slate was quite difficult, but it's really table stakes for what I plan on doing longterm, and I don't even know where to begin to do virtualized windowing in Prosemirror.


The Slate rewrite looks much better than the previous version. It was a big step for them to remove Immutable, which had to happen given the state of that project (which, incidentally, got new maintainers last week). I'm not surprised it's rolling steady now. It's good that Ian delegated smoothly. I wondered how he did that rewrite while simultaneously working at Segment as a cofounder…

I agree that Slate is nicer than ProseMirror with a more standard code style, the fact that it's not scattered among a bunch of repos, and that it's written in TypeScript. And it's not great that ProseMirror seems to have a bus factor = 1, maybe 2 or 3. That's not the case with Slate right currently, right?

It's remarkable you built cocalc with Slate. And the virtualization. Really big work.


Slate has a bunch of people that are making PR's, which is why there are 80+ open PR's right now. There's evidently been 403 distinct contributors to Slate. I don't know how to see on GitHub, but I remember a Slate developer saying Ian had delegated something like 10+ people as having commit rights for Slate (I'm not one of them). The introductory documentation that Ian wrote for Slate is also really useful and a pleasure to read, and when you need more deeply technical documentation the source code serves that purpose well. Thanks regarding the encouragement regarding cocalc+Slate; I need to get back to that part of Cocalc soon!


How does virtualization play with text search? Did you end up having to roll your own?

I'm still working on migrating my team's Slate implementation from 0.47 to 0.5x.. the new API is simultaneously simpler but also.. harder for me to grok? Maybe I just am having trouble with the documentation because I end up reading the source more often than not.


Yes, I very much have to implement my own text search. There are many custom elements, so I would have to roll my own anyways at some point.

In my experience, I think the official documentation is just an introduction and overview, and that you have to read the source code of Slate when you're serious about doing development using it. This is not necessarily bad, since the source code is pretty readable, and the fact everybody seriously using slate is reading the source increases the number of contributors.


I don't mind reading the source, but it can feel a lot slower than it needs to to get the information I need. Of course, it's completely understandable that it would be lacking because it did just (relatively speaking) undergo a major refactor.

I can tell though that I'm going to have to write my own documentation (for my coworkers) about how to use Slate, because for me, having explicit examples of proper function usage is incredibly helpful and there isn't much of that in the documentation.. so we're basically just left with the existing examples which don't come close to covering all of the options each function has.

I'll also probably have to include a migration guide (e.g. if you used to do (a) with the old API, try (b) in the new one.. (it's probably just Editor.nodes))


That's my experience. I own a fork of Slate and Slate plugins that I've been doing my best to maintain, as well as a wrapper: https://github.com/roast-cms/french-press-editor. My project is small enough not to have bandwidth to upgrade Slate or switch to another editor but popular enough to keep alive and maintain two years past the version release I solidified. The implementation I have isn't very buggy, I've used it almost every day and have over a hundred users who successfully used it as well. There was only one time when a serious bug surfaced, the rest being minor inconveniences. This is the implementation: https://www.analog.cafe/write/draft


What features of Slate put it closest to Notion's editor compared to other frameworks besides the obvious one that Slate's view layer is built on top of React?

Is it somehow that Slate is more suitable handling asynchronous data (e.g. server generated uuids for each block, recursively fetching content for each block and its children)?


I've been building out a very feature-rich editor for the last few months using Slate. Looked at all the alternatives and fell in love with Slate's model over all others. It's been great so far, far better than the old Quill editor I've been tasked with replacing. My only complaints are related to documentation, and a few footguns if you misuse the provided utilities, or get too crazy with your rendered react elements.

Test-driven development is not my usual approach to coding, but it's extremely beneficial (and easy to do) with slate. Especially for the recursive normalizer, which has grown very complex and fragile but plays an extremely important role in my editor.

I worry about long term maintenance of the library, only a small trickle of contributions come in. But in practice its been a perfectly stable library.

RTE in the browser is a full-time job even with a library like slate. Be warned!


I also had a to pick a rich text editor to build a "better Confluence" [1]. Initially started with Quill, but Quill is really limited and for example can't support rich text inside tables, only simple text.

So after some research I picked prosemirror which is used by Confluence but prosemirror is the harder to learn and the most flexible, there was also Slate which is used by Slite but it was not as flexible as prosemirror and less robust . Notion and Google docs are using their own custom editor BTW.

If you are looking for a rich text editor, there are surprisingly a lot of ressources. Either search for "rich text editor", "slate vs prosemirror" in Google, or my preferred way to get quality information. Search "prosemirror" in the HN search and read the threads [2]

The big complain I have with prosemirror is the fact that there is no official repository of Plug-ins instead everyone is rebuilding everything

[1] https://dokkument.com/

[2] https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...


> there is no official repository of Plug-ins instead everyone is rebuilding everything

To be fair, both Slate and ProseMirror call themselves frameworks for building rich text editors as opposed to drag-and-drop editors themselves.

The best way to build an editor yourself then would be to look at other existing editors using the same framework, and try to understand the architecture and usage.


Been looking for something like this but minus React for _ages_. I'd like our users to build their own RTE according to their needs, having a common data model on every one of them.

Is there such a thing out there?


Have a look at ProseMirror, let us know if this seems like what you want!

https://prosemirror.net/


Would second ProseMirror. It was powerful enough for me to build essentially a code editor: https://qworp.com/


Would third prosemirror. Used it extensively for years


Based on ProseMirror, more popular than raw ProseMirror, inspired by Slate (years ago), but framework-agnostic and more advanced in some areas (like collaborative editing):

https://tiptap.dev


Slate is architected so everything that actually involves React is in a separate plugin called "slate-react". As explained here https://github.com/ianstormtaylor/slate#packages there's a package called "slate" that's "Slate's core data model logic.", and there's another package called slate-react that is "React components for rendering Slate editors.". For example, I just searched npm and quicly found "slate-vue" (https://www.npmjs.com/package/slate-vue) which is Slate, but with a Vue plugin instead of React.


Quill is ok


My quibble with Quill is its long-standing and may not ever be fixed lack of support for tables.


I like that initiative. Ian did a great job.


I would rather want a Typora-like (but nicely embeddable) MarkDown editor with realtime visualization (instantly applying relevant visual formatting to MarkDown elements) to ensure user's mental model of the document and the actual underlying model are always the same. IMHO classic WYSIWYG editors are evil.



Nice, thank you.

I have tried the demo[1] and couldn't find how to switch to MarkDown code mode. In Typora I can just press Ctrl+Slash.

[1] https://saul-mirone.github.io/milkdown/#/online-demo


Does anyone knows about something similar but for building graphical HTML editors? I need to create an editor for non technical people where they will be able to drag and drop certain elements and set some of their properties. And the result of this building has to be html and css.


1) https://github.com/react-page/react-page (comes with a Slate plugin actually) 2) https://grapesjs.com/


No image support? It’s the main thing that’s a pain in the ass to support.


There are editors that handle images very well by default, like Quill or Trix.

If you start diving deeper you’ll find out that image handling is just super complex and the behaviour is dependant on what you’re building. Then you’ll be happy to have full control about the behaviour with editors like Slate, ProseMirror or Tiptap.


The customisability is definitely a plus, you can make slate fit in perfectly with almost any UI. Whilst you don't get complex image handling by default, I think their image handling example [0] is a really nice minimal implementation which is quite intuitive.

[0] - https://www.slatejs.org/examples/images


Just wanted to note to those thinking of using it: beware of Quill. I used it for my project, but it was not made for saving and then displaying the rich text. At least for me, it was a hassle figuring out how to accomplish this.


I’ve started using quill recently (for users to write, save and then display). I’m just rendering the saved structure and disable the editor parts for “display”. I’m happy with it


That is not how anyone would reasonably expect to be able to display rich text.


The basic package is bare though very much functional. The problem with whatabout's for such an editor is what do you put behind "image support"?

Some would need uploads, others just links, then copy and pasting, alt, captions, styling, etc...

Slate makes it easy to extend its core with custom blocks. Now, it's definitely some work but it's actually very intuitive to work with.


For those that want more on top of Slate, there's Plate (fka slate-plugins) which provides a lot of extras as a separate package.

https://plate.udecode.io/ https://github.com/udecode/slate-plugins

Similarly, there's slate-yjs for integration with yjs, and so forth.


For those that need something more mature that is very stable CKEditor is a very battle-tested alternative.


Question. I'm building a .NET CMS, and want "on page editing". This entails having a string property mapping to, lets say, a headline.

So while editing on page, I want to click the rendered heading and be able to select text and start editing it - without necessarily being able to influence the HTML in any way. Just the text, no styling.

tldr of above: dont allow ctrl+b or pasting of styled content (and probably prohibit enter presses or pasting newlines), only plain text.

Also, if the heading is an inline element inside the h1 element, and its bunking together with other stuff (icons or whatnot), editing of the headline span only should still work.

tldr - edit an elements text inline, in fact the element may be display:inline itself

I had immense difficulty getting this to work with Quill - it wasn't customizable enough. Would Slate work?




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

Search: