Lexical Setup Isn’t What You Think — Here’s the Real Minimal Setup
If you’re trying to set up Lexical for the first time and thought:
“Just install lexical and start typing.”
Wrong. I made that mistake too — and lost hours figuring it out.
So I'm writing this post to help save you time.
Installing lexical
alone won’t give you a working editor
Lexical is just the core engine. It handles state and structure behind the scenes, but it doesn’t:
- Let you type
- Show any content
- Handle user input
That’s because it’s immutable by design. It needs extra plugins to actually work like a text editor.
What you really need
To make Lexical work, you must also install one of these:
Type of Editor | Package to Install |
---|---|
Plain Text | @lexical/plain |
Rich Text | @lexical/rich-text |
These plugins handle the UI and typing behavior for you.
Quick Setup
Install the packages:
npm install lexical @lexical/plain
Then create a simple index.html
and editor.js
:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Lexical Vanilla Example</title>
<style>
#editor {
border: 1px solid #ccc;
min-height: 100px;
padding: 10px;
}
</style>
</head>
<body>
<div id="editor" contenteditable="true"></div>
<script type="module" src="./editor.js"></script>
</body>
</html>
import { createEditor } from 'lexical';
import { PlainTextPlugin } from '@lexical/plain';
const editorElement = document.getElementById('editor');
// Create the editor
const editor = createEditor();
// Register plain text functionality
editor.registerRootElement(editorElement);
// Add basic typing support (plugin)
PlainTextPlugin({
editor,
contentEditable: editorElement,
placeholder: 'Type something...',
});
Bonus (Solid.js Example)
import { createSignal, onCleanup, onMount } from "solid-js";
import { createEditor } from "lexical";
import { registerRichText } from "@lexical/rich-text";
const editorConfig = {
namespace: 'editor',
onError: console.error
}
export default function Editor() {
let editorRef: HTMLElement | undefined = undefined;
const editor = createEditor(editorConfig);
const [editorState, setEditorState] = createSignal();
registerRichText(editor);
editor.registerUpdateListener(({ editorState }) => {
editorState.read(() => {
setEditorState(editor.getEditorState());
});
});
onMount(() => {
if (!editorRef) return;
editor.setRootElement(editorRef);
onCleanup(() => {
editor.setRootElement(null);
});
})
return (
<div
ref={editorRef}
contentEditable
/>
);
}
This is the minimal setup required to integrate Lexical.js using plain JavaScript.
Happy Editing!