Skip to content

Luthor (`@lyfie/luthor`) Architecture

This document explains how the plug-and-play package is organized, why it is split the way it is, and how it composes @lyfie/luthor-headless.

@lyfie/luthor is the preset-oriented package:

  • It provides out-of-the-box editor UIs and preset composition.
  • It consumes and re-exports the headless runtime from @lyfie/luthor-headless.
  • It keeps feature implementation grounded in headless extensions while focusing on UX composition.
packages/luthor/src/
index.ts # package entrypoint
core/ # reusable preset UI + adapters
presets/ # concrete preset assemblies
  • src/index.ts
    • Re-exports presets/* and core/* public API.
    • Exports headless namespace to provide direct access to @lyfie/luthor-headless from one package import.

src/core contains preset-reusable modules:

  • typed command/state contracts (types.ts)
  • toolbar / floating toolbar / command palette / slash and emoji menus
  • command catalog and keyboard shortcut wiring
  • source-mode formatting helpers (HTML/Markdown/JSONB)
  • preset config helper (createPresetEditorConfig)
  • adapter that bridges headless floating-toolbar extension with React UI

This layer intentionally avoids hard-coding one preset shell.

src/presets/extensive/* provides the flagship preset:

  • static preset metadata (preset.ts)
  • extension stack composition (extensions.tsx)
  • final editor shell component (ExtensiveEditor.tsx)

src/presets/index.ts exposes a registry model for discoverable presets.

  1. ExtensiveEditor creates an editor system provider using createEditorSystem.
  2. Headless extensions provide command/state capabilities.
  3. Toolbar and FloatingToolbar consume the typed command surface (CoreEditorCommands).
  4. generateCommands builds command metadata for command palette and slash commands.
  5. Keyboard shortcuts are attached via registerKeyboardShortcuts.
  6. Visual/source mode switching runs import/export conversion routines.
  • Keeps Lexical-heavy behavior in @lyfie/luthor-headless.
  • Preserves a reusable UI composition layer for future presets.
  • Allows a single package (@lyfie/luthor) for plug-and-play adoption.
  • Maintains typed boundaries between extension capability and UI rendering.

From packages/luthor/package.json:

  • Runtime deps include @lyfie/luthor-headless, Lexical packages (^0.40.0), lexical, and lucide-react.
  • React and React DOM are peers: ^18.0.0 || ^19.0.0.
  • Package version: 2.2.0.