[HN Gopher] Lexical - a web text editor framework that powers Fa... ___________________________________________________________________ Lexical - a web text editor framework that powers Facebook Author : trueadm Score : 147 points Date : 2022-06-20 18:08 UTC (4 hours ago) (HTM) web link (playground.lexical.dev) (TXT) w3m dump (playground.lexical.dev) | a-priori wrote: | How does this compare to Draft.js, another rich text editor | created by Facebook? | | https://draftjs.org/ | trueadm wrote: | Check out this answer I used in a previous HN thread: | | https://news.ycombinator.com/item?id=31020205 | rsstack wrote: | I'd love to use Lexical to replace what we're using today. I've | been checking in on the repository every few weeks. However, | there are many features that are still pending | https://github.com/facebook/lexical/projects/1 . We need several | of the features that are "V1.0" and we obviously need the | stability of a 1.0 SemVer release :) | | Is there a general timeline goal for the V1.0 release? | trueadm wrote: | What features in particular are you missing? We haven't really | discussed a deadline for 1.0, as we've been trying to take our | time making sure each release is impactful and correct. | tester756 wrote: | That's really good | | How do people search for jobs that work in this problem domains - | parsers / editors / compilers? | trueadm wrote: | For Meta, or in general? For Meta, there are plenty of teams | that require some infra knowledge around these common concepts. | It's been fairly straightforward to find a team as a front-end | engineer that allows you to excel in these areas at Meta (once | you're successful in the interview loops). | barbinbrad wrote: | We're trying to choose between Lexical and Slate at work. Do you | have any code examples that would be similar to this? | | Example: https://www.slatejs.org/examples/richtext | | Code: | https://github.com/ianstormtaylor/slate/blob/main/site/examp... | jitl wrote: | <sarcasm>If you are planning to build a Notion competitor, I | recommend Slate</sarcasm>. Seriously though, if you need to | support Android or CJK, you should understand Slate's | limitations before you buy into it. I think ProseMirror is the | best choice today because it has been around for a long time | and has battle-tested MutationObserver logic. Lexical is worth | considering depending on your risk appetite. It also uses | MutationObserver and appears to approach Android correctly. I | haven't read enough of the code to recommend it yet. In Slate, | Android is a second-class citizen with an extremely bare-bones | MutationObserver reconciler. The main codebase only uses | beforeInput.preventDefault which doesn't work on Android. | trueadm wrote: | ProseMirror is a great choice. Lexical might offer you more | mileage if you're working with React (especially React 18 and | the new concurrency features) and are happy to invest into a | project that is still pre 1.0. | jamesfisher wrote: | Why the sarcasm? | jitl wrote: | I work at Notion and recently rebuilt much of the editor | core, and I don't think Slate is a good choice because it | considers nice, simple code more important than CJK or | Android support. Notion doesn't use Slate or any other | editor framework. I just study a lot of editor core code. | nicce wrote: | I don't understand the Android argument - these are | mainly meant for browsers right? | jitl wrote: | 1. Android also has a browser. It is an important | platform with many users. | | 2. Building an editor is so complicated that most | organizations want to do it only once. They build a web | editor, and wrap it in a native app. The shell like file | browser, sharing screens, etc are "native" but the editor | surface is a webview. This is how Quip, Dropbox Paper, | Google Docs, Notion, etc work. Even iOS worked this way | initially for all editable styled text (per https://twitt | er.com/kocienda/status/1400484473540513792?s=21...) | | 3. If you are going to bet the core competency of your | business on a framework, it's important to understand the | motivations and limitations of said framework. | jamesfisher wrote: | Thanks, I see. I'm using Slate for TigYog.app, and fairly | happy with it, but neither CJK nor Android are important | there. | | Btw I'd love to see any public posts about the | architecture of the Notion editor! | jitl wrote: | Slate has a nice, approachable API from a React | perspective. I think depending on your project it could | be an okay trade off. | | I co-wrote a post about our editor internals after | finishing up the recent re-work but we decided not to | publish it to conserve our Competitive Advantage. | barbinbrad wrote: | Thanks for the advice! | trueadm wrote: | The Lexical playground is one giant kitchen-sink example all | written in React. You could check out the code for it locally | and `npm run start` and play around with removing/adding | plugins. You can also check out some examples on Codesandbox: | https://codesandbox.io/s/lexical-rich-text-example-5tncvy | barbinbrad wrote: | Thanks! Very helpful. | latchkey wrote: | It is interesting (and cool) that this uses Typescript over Flow. | It seems like Flow is still being developed too. | | Just looking at the top level package.json [1], I wonder at which | point you abstract all those copy/pasted targets into a script | that takes an argument. | | [1] | https://github.com/facebook/lexical/blob/main/package.json#L... | _the_inflator wrote: | Even FB engineers can learn a thing or two. ;) | | Good tip. | latchkey wrote: | Thanks! I guess the last 20 years of writing code were not a | waste after all. Heh. =) | trueadm wrote: | I'm the author of Lexical and one of the many engineers working | on Lexical full-time at Meta. If you'd like to know anything, or | ask any questions, please do! | | For those of you looking for the sourcecode for the playground, | you can find it here: | | https://github.com/facebook/lexical/tree/main/packages/lexic... | | We also have a Discord channel you can check out: | | https://discord.gg/KmG4wQnnD9 | jjuliano wrote: | Hi, I did (or somewhat invented/devised) a similar concept, but | for visually programming UI design. See: | https://jjuliano.github.io/markdown-ui/docs/container.html | nehalem wrote: | Thanks for the offer, let me take you up on this. Could you | compare Lexical and Prosemirror from an architecture | perspective? What motivated your decisions in that regard? | trueadm wrote: | Sure thing. I actually wrote up a really detailed response to | this on ProseMirror's discussion board: | | https://discuss.prosemirror.net/t/differences-between- | prosem... | | Ultimately though, there are many similarities between the | two - intentionally so. We were inspired by ProseMirror and | some of its APIs and approaches. I think the biggest | underlying differences are in how we tackle things from a DX | perspective. We tried to bring a more composable API to | making text editors work - from the plugin patterns, how | updates and reads work, to how you listen for changes and | react to them. Much of this was inspired by my prior work | working on the React core team and from creating Inferno. | samwillis wrote: | Interesting you say DX is a large aspect of what you are | going for. ProseMirror is awesome but the API can be | somewhat complex for simple things (but at the same time | incredibly powerful when you get to understand it). I | absolutely love TipTap[0] which is providing a much more | user friendly API on top of ProseMirror, along with a clean | Plugin system. | | Going to have to have a play with Lexical, excited to see | Yjs support! | | [0]: http://tiptap.dev | pixel_tracing wrote: | Hey since you work at Meta can you find when code support / | markdown will be added to text editing components? | | It's so frustrating posting code snippets to friends threads on | FB | trueadm wrote: | Lexical supports code support / markdown. We actually use it | a lot for Workplace, which is a kind of Facebook-like website | for companies. It's really down to the product surfaces what | features from Lexical they choose to use. | jacobsimon wrote: | Hey on my business's website we currently use draft.js for | our user discussion product and we convert the user input | to markdown for storing in our db. How hard would it be to | switch to Lexical and does it support rendering from | markdown syntax? Do you recommend any other approaches for | safe storage and rendering of rich text? Thanks! | trueadm wrote: | Lexical has markdown support via `@lexical/markdown`. See | https://lexical.dev/docs/api/lexical-markdown. | acywatson wrote: | I work at Meta on the Lexical team - yes, Lexical | supports markdown and rendering from markdown syntax. | Lexical isn't a drop-in replacement for Draft, but we're | migrating all of our surfaces internally and it isn't | particularly difficult, especially if you aren't storing | in the DraftJS-specific format. As for alternatives, you | can also consider storing it as JSON, which Lexical | supports. | hit8run wrote: | How does it feel to work for one of the worst companies out | there? Can you ignore it or does it bother you from time to | time? Is it worth it? | 8organicbits wrote: | How is Facebook using this? | trueadm wrote: | It's used throughout Meta. The Post Composer, and Comment | Composer on Facebook/Workplace, on Messenger, WhatsApp Web, | Instagram Messenger, and many other surfaces too! | pxeger1 wrote: | In what sense does this "power" Facebook? Do you mean it's used | for most or some specific text editing components of Facebook? | trueadm wrote: | It's replacing any previous web text editor UX components that | we had in the past (likely DraftJS). We're also building | Lexical for iOS which is slowly rolling out across iOS devices | too. | andrewshadura wrote: | Well, I want the previous editor back. In fact, just give me | a text area. The current editor breaks the selection and, in | turn, the clipboard manager, it doesn't work well with | Compose and dead keys, and it sometimes ties itself into a | knot, and the text can't be edited anymore. | danuker wrote: | When pasting links stopped working for me is about when I | stopped using Facebook. | | It's 2022 and we're reinventing every wheel, but in the | browser. | | GitHub has a Markdown editor with a paste handler | (converting tables and such). It once had a bug. I had to | disable handlers in the browser to be able to paste. | jitl wrote: | How do you handle Android and multi-lingual input? Writing the | state machine to deal with Chrome/Android's bananas selection | bugs in Notion's editor gave me a lot of headaches. Do you add | extra DOM nodes on Android? Any key insights that help deal with | IME on Android? | trueadm wrote: | Android is indeed a headache to support. The biggest issue is | how all keyboards force composition on all keystrokes, meaning | you're constantly having to read the DOM input and work out | what might have been entered. We don't use extra DOM nodes, but | we do listen to `beforeinput`, `input` and use DOM | MutationObserver to try and detect common Android patterns. I'd | search this module for references to Android: | | https://github.com/facebook/lexical/blob/main/packages/lexic... | pier25 wrote: | It's currently a bit broken on Android. | | I select some text and then try to change the font size. The | selection is lost when tapping on the font size menu. | | ProseMirror does keep the selection intact. | jitl wrote: | ANDROID!!!!! | trueadm wrote: | It's probably because we're using a native select element, | which likes to steal selection on Android. | jitl wrote: | > event.timeStamp < lastKeyDownTimeStamp + | ANDROID_COMPOSITION_LATENCY | | I tried so hard to avoid adding timeouts/timestamp logic for | Android because it feels like a nondeterministic hack. In the | end I gave up and did something similar. | | I also found beforeInput doesn't offer much solace on Android | or with CJK language, because messing around with | preventDefault or the DOM during composition disturbs the | user. | | One weird thing I never figured out is that if the user puts | the selection in an empty block, GBoard wants to jump to the | nearest word in a different paragraph. We do some brutal | hacks to get around that :-/ | | I read your comment on ProseMirror forum about preventing | interference from Granmarly, etc. Do you do this by reverting | MutationRecords? Where is the code/docs for that? | trueadm wrote: | Yeah, I really wanted to avoid them too. There doesn't seem | a good way. The issue you describe with selection jumping | is a well known issue with GBoard. Here's the logic for the | mutation handling: | | https://github.com/facebook/lexical/blob/main/packages/lexi | c... | jitl wrote: | https://github.com/facebook/lexical/blob/5802651c24d88b2f | 7d2... | | > // Check for any random auto-added <br> elements, and | remove them. | | > // These get added by the browser when we undo the | above mutations | | > // and this can lead to a broken UI. | | This made me laugh out loud. Browsers! | | Until here our approach looked quite similar. Leave the | observer connected during reverts and avoiding double- | peocessing using .takeRecords never occurred to me, I | always disconnect it. Maybe some of these brs are causing | chaos... | trueadm wrote: | Now thinking about it, I don't know why we didn't just do | that. There must have been a reason, but I really can't | recall what it was. If you're ever interested in | contributing, this would be an epic contribution! :D | canadiantim wrote: | Does Lexical require react? | thorncorona wrote: | I realize this isn't probably your product surface but do you | have any idea why FB messenger still has issues with double | texting using the text box? | | Also, how do you guys design to reduce latency in Lexical? Esp | considering the fluidity of modern chat clients ex. Telegram | which are much more performant. ___________________________________________________________________ (page generated 2022-06-20 23:00 UTC)