Getting Started with Lexical
Lexical is a powerful, extensible text editor framework developed by Meta, designed for performance, reliability, and flexibility. If you’re looking to build a rich text editor in your React application, Lexical provides a modern, modular approach that’s easy to integrate and customize.
In this post, we’ll walk through the basics of setting up Lexical with React, using the lexical
and @lexical/react
packages, and show you how to create a simple, extensible rich text editor.
Why Lexical?
- Performance: Lexical is built for speed, even with large documents.
- Extensibility: Easily add plugins and custom nodes.
- Accessibility: Designed with accessibility in mind.
- React Integration: First-class support for React.
Setting Up Your Project
First, install the necessary packages:
npm install lexical @lexical/react
Or, if you’re using Yarn:
yarn add lexical @lexical/react
Creating a Basic Editor
Let’s look at a minimal example, inspired by the examples/react-rich
demo in the Lexical repo.
import React from 'react';
import {LexicalComposer} from '@lexical/react/LexicalComposer';
import {RichTextPlugin} from '@lexical/react/LexicalRichTextPlugin';
import {ContentEditable} from '@lexical/react/LexicalContentEditable';
import {HistoryPlugin} from '@lexical/react/LexicalHistoryPlugin';
import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';
// Optional: Your custom theme and plugins
import ExampleTheme from './ExampleTheme';
import ToolbarPlugin from './plugins/ToolbarPlugin';
import TreeViewPlugin from './plugins/TreeViewPlugin';
const placeholder = 'Enter some rich text...';
const editorConfig = {
namespace: 'React.js Demo',
theme: ExampleTheme,
onError(error) {
throw error;
},
// Add custom nodes if needed
nodes: [],
};
export default function App() {
return (
<LexicalComposer initialConfig={editorConfig}>
<div className="editor-container">
<ToolbarPlugin />
<div className="editor-inner">
<RichTextPlugin
contentEditable={
<ContentEditable
className="editor-input"
aria-placeholder={placeholder}
placeholder={
<div className="editor-placeholder">{placeholder}</div>
}
/>
}
ErrorBoundary={LexicalErrorBoundary}
/>
<HistoryPlugin />
<AutoFocusPlugin />
<TreeViewPlugin />
</div>
</div>
</LexicalComposer>
);
}
Key Components
- LexicalComposer: The root provider for your editor, takes an
initialConfig
object. - RichTextPlugin: Handles the main editing area, including content editable and placeholder.
- ContentEditable: The actual editable div.
- HistoryPlugin: Adds undo/redo support.
- AutoFocusPlugin: Focuses the editor on mount.
- ToolbarPlugin, TreeViewPlugin: Example custom plugins for toolbar and document tree view.
Customization
Lexical is highly customizable. You can:
- Add Plugins: Create your own plugins for features like toolbars, markdown, collaboration, etc.
- Define Custom Nodes: Extend the editor with new node types (e.g., tables, mentions).
- Style the Editor: Use your own themes and CSS.
Next Steps
- Explore the Lexical documentation for more advanced features.
- Check out the
examples/
directory in the Lexical repo for real-world usage. - Try building your own plugins and custom nodes!
Lexical makes it easy to build a modern, performant, and accessible rich text editor in React. With its modular architecture and React-first approach, you can start simple and scale up to complex editing experiences.
Happy editing!
Using Lexical with Other Frameworks
While Lexical is designed with React in mind, its core editor can be used with other frameworks or even plain JavaScript. Here are some quick examples:
Vanilla JavaScript
You can use Lexical’s core API to create an editor without any framework:
import { createEditor } from 'lexical';
const editor = createEditor();
const editableDiv = document.getElementById('editor');
// Listen for updates
editor.registerUpdateListener(({editorState}) => {
// Handle editor state changes
const json = editorState.toJSON();
console.log(json);
});
// Set initial content
editor.setEditorState(editor.parseEditorState('<p>Hello, Lexical!</p>'));
// Attach to DOM (you'll need to handle rendering and events)
// See https://lexical.dev/docs/standalone for more details
Vue
There are community projects and wrappers for Vue. One example is lexical-vue:
<script setup>
import { LexicalComposer, RichTextPlugin } from 'lexical-vue';
const config = {
namespace: 'VueDemo',
theme: {},
onError: (e) => { throw e; },
};
</script>
<template>
<LexicalComposer :initialConfig="config">
<RichTextPlugin />
</LexicalComposer>
</template>
Svelte
You can use Lexical’s core API directly in Svelte components. For more advanced integration, check out svelte-lexical:
<script>
import { onMount } from 'svelte';
import { createEditor } from 'lexical';
let editor;
onMount(() => {
editor = createEditor();
// Set up listeners, state, etc.
});
</script>
<div id="editor" contenteditable="true"></div>
For more, see:
Lexical’s modular core makes it possible to build editors in any environment. If you’re using a different framework, check for community wrappers or use the core API directly!