README.md

August 11, 2026 ยท View on GitHub

Luthor

TypeScript-first rich text editor ecosystem for React, built on Lexical.

:rocket: Production-ready presets + :jigsaw: headless extension runtime + :unlock: MIT license

NPM - @lyfie/luthor NPM - @lyfie/luthor-headless Quality Gates

Luthor feature preview

:sparkles: Why Luthor

Luthor is an open-source rich text editor ecosystem designed for teams that want modern DX without editor lock-in.

  • :package: Two-package model: start fast with presets, go deep with headless composition
  • :shield: TypeScript-first APIs: safe command/state integrations
  • :zap: Lexical-powered: modern performance and extensibility
  • :art: UI freedom: build custom editor experiences when product requirements evolve
  • :package: ESM-first distribution: optimized for modern React bundling

:package: Packages

PackagePurposeBest fornpm
@lyfie/luthorPlug-and-play editor presets + polished UIShipping quickly with minimal setupnpm
@lyfie/luthor-headlessHeadless extension runtime and typed editor systemFull UI control and custom workflowsnpm

:bookmark_tabs: Preset Metadata Policy

Luthor now applies a strict source-metadata policy:

  • Metadata-free presets: MarkDownEditor, HTMLEditor, LegacyRichEditor
    • These presets run with sourceMetadataMode="none" and avoid metadata envelopes by default.
  • Markdown-native preset: PapyraEditor
    • Runs with sourceMetadataMode="none"; markdown is the source of truth, with Obsidian-style embeds and a host adapter seam.
  • Metadata-friendly preset: ExtensiveEditor
    • Preserves metadata only when an attribute is not natively representable in Markdown/HTML.

Examples of metadata that can still be emitted in metadata-friendly presets:

  • Unsupported custom nodes
  • Markdown-non-native rich attrs (advanced table attrs, link target/rel, runtime image attrs, advanced embed attrs)
  • HTML-only non-native extras (for example frontmatter)

Migration note:

  • Existing legacy metadata comments remain import-compatible.
  • Exporters now emit fewer metadata comments for representable features.

:rocket: Quick Start

pnpm add @lyfie/luthor
import { ExtensiveEditor } from "@lyfie/luthor";
import "@lyfie/luthor/styles.css";

export function App() {
  return <ExtensiveEditor placeholder="Start writing..." />;
}

Syntax highlighting notes:

  • prismjs is already installed transitively through @lexical/code.
  • @lyfie/luthor presets use Lexical default language options and syntax tokens by default.
  • Disable per preset with isSyntaxHighlightingEnabled={false}.
  • Customize tokens with syntaxHighlightColorMode="custom" and syntaxHighlightColors.

Need full control?

pnpm add @lyfie/luthor-headless lexical @lexical/code @lexical/link @lexical/list @lexical/markdown @lexical/react @lexical/rich-text @lexical/selection @lexical/table @lexical/utils react react-dom

:computer: Monorepo Development

Requirements:

  • Node >=20
  • pnpm@10.4.1

Install + run:

pnpm install
pnpm dev

Quality gates:

pnpm build
pnpm lint
pnpm format
pnpm size:check
pnpm check:rule-contracts

Windows + WSL split workflow (Cloudflare/OpenNext operations):

pnpm run web:preview:wsl
pnpm run web:deploy:wsl

:handshake: Contributing

  1. Fork + clone the repo.
  2. Create a feature branch.
  3. Run checks locally (pnpm lint, pnpm build, pnpm test where applicable).
  4. Open a PR with a clear scope and screenshots/GIFs for UI changes.

Issue tracker: github.com/lyfie-org/luthor/issues

:chart_with_upwards_trend: Community

Star History

Star History Chart

Contributors

Contributors

:page_facing_up: License

MIT (c) Luthor Team