Overview
The @lexical/code package provides code block functionality for Lexical with syntax highlighting support using Prism.js.
Installation
npm install @lexical/code prismjs
Nodes
CodeNode
Represents a code block with language support.
Programming language for syntax highlighting (e.g., ‘javascript’, ‘python’)
Methods:
Returns the code block’s language
Sets the code block’s language
CodeHighlightNode
Represents a syntax-highlighted token within a code block.
The Prism token type (e.g., ‘keyword’, ‘string’, ‘comment’)
Factory Functions
$createCodeNode
Creates a new CodeNode.
function $createCodeNode(language?: string): CodeNode
The programming language (defaults to value from getDefaultCodeLanguage())
Example:
import { $createCodeNode } from '@lexical/code';
editor.update(() => {
const code = $createCodeNode('javascript');
const codeText = $createTextNode('const x = 42;');
code.append(codeText);
$getRoot().append(code);
});
$createCodeHighlightNode
Creates a new CodeHighlightNode.
function $createCodeHighlightNode(
text: string,
highlightType?: string
): CodeHighlightNode
Type Guards
$isCodeNode
function $isCodeNode(node: LexicalNode | null | undefined): node is CodeNode
$isCodeHighlightNode
function $isCodeHighlightNode(
node: LexicalNode | null | undefined
): node is CodeHighlightNode
Syntax Highlighting
registerCodeHighlighting
Registers Prism-based syntax highlighting.
function registerCodeHighlighting(
editor: LexicalEditor,
tokenizer?: PrismTokenizer
): () => void
Custom tokenizer (defaults to Prism-based tokenizer)
Returns: Cleanup function
Example:
import { registerCodeHighlighting } from '@lexical/code';
import Prism from 'prismjs';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-javascript';
const unregister = registerCodeHighlighting(editor);
PrismTokenizer
Tokenizer interface for syntax highlighting.
type PrismTokenizer = {
tokenize(
code: string,
language: string
): Array<string | Prism.Token>;
}
Language Utilities
getDefaultCodeLanguage
Gets the default code language.
function getDefaultCodeLanguage(): string
normalizeCodeLang
Normalizes a language string to a valid Prism language.
function normalizeCodeLang(lang: string): string
getLanguageFriendlyName
Gets a human-friendly name for a language.
function getLanguageFriendlyName(lang: string): string
Example:
getLanguageFriendlyName('js'); // Returns 'JavaScript'
getLanguageFriendlyName('python'); // Returns 'Python'
getCodeLanguages
Gets all available code languages.
function getCodeLanguages(): string[]
getCodeLanguageOptions
Gets language options for a dropdown.
function getCodeLanguageOptions(): Array<[string, string]>
Returns: Array of [value, label] pairs
Constants
DEFAULT_CODE_LANGUAGE
const DEFAULT_CODE_LANGUAGE = 'javascript'
CODE_LANGUAGE_MAP
Map of language aliases to canonical names.
const CODE_LANGUAGE_MAP: Record<string, string>
CODE_LANGUAGE_FRIENDLY_NAME_MAP
Map of language codes to friendly names.
const CODE_LANGUAGE_FRIENDLY_NAME_MAP: Record<string, string>
Code Utilities
$getFirstCodeNodeOfLine
Gets the first code node in a line.
function $getFirstCodeNodeOfLine(): CodeHighlightNode | TextNode | null
$getLastCodeNodeOfLine
Gets the last code node in a line.
function $getLastCodeNodeOfLine(): CodeHighlightNode | TextNode | null
$getStartOfCodeInLine
Gets the start offset of code in the current line.
function $getStartOfCodeInLine(): number
$getEndOfCodeInLine
Gets the end offset of code in the current line.
function $getEndOfCodeInLine(): number
$getCodeLineDirection
Gets the text direction of the current code line.
function $getCodeLineDirection(): 'ltr' | 'rtl' | null
Extension
CodeExtension
Bundles CodeNode, CodeHighlightNode, and syntax highlighting.
import { createEditor } from 'lexical';
import { CodeExtension } from '@lexical/code';
const editor = createEditor({
extensions: [CodeExtension]
});
Types
SerializedCodeNode
type SerializedCodeNode = Spread<
{
language: string | null | undefined;
},
SerializedElementNode
>
Complete Example
import { createEditor } from 'lexical';
import {
CodeExtension,
$createCodeNode,
registerCodeHighlighting,
getCodeLanguageOptions
} from '@lexical/code';
import Prism from 'prismjs';
import 'prismjs/components/prism-javascript';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-typescript';
const editor = createEditor({
extensions: [CodeExtension],
namespace: 'CodeEditor',
onError: (error) => console.error(error)
});
editor.setRootElement(document.getElementById('editor'));
// Register syntax highlighting
const removeHighlighting = registerCodeHighlighting(editor);
// Insert a code block
editor.update(() => {
const root = $getRoot();
const code = $createCodeNode('typescript');
const codeText = $createTextNode(
'function greet(name: string): void {\n' +
' console.log(`Hello, ${name}!`);\n' +
'}'
);
code.append(codeText);
root.append(code);
});
// Get available languages for UI
const languages = getCodeLanguageOptions();
// Returns: [['javascript', 'JavaScript'], ['python', 'Python'], ...]
// Later, cleanup
removeHighlighting();
Theming
To style syntax highlighting, define CSS for Prism token classes:
.token.comment { color: #6a9955; }
.token.keyword { color: #569cd6; }
.token.string { color: #ce9178; }
.token.function { color: #dcdcaa; }
.token.number { color: #b5cea8; }
.token.operator { color: #d4d4d4; }