[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)