@lyfie/luthor is the preset layer on top of @lyfie/luthor-headless.
It gives you ready-made editor components, while still using typed extension composition under the hood.
ExtensiveEditor) receives props.createExtensiveExtensions(...) builds the exact extension array.createEditorSystem(...)) mounts those extensions.jsonToMarkdown / markdownToJSONjsonToHTML / htmlToJSONpackages/luthor/src/presets/extensive: base preset, extension assembly, and default UX.packages/luthor/src/presets/*: wrappers around ExtensiveEditor (Compose, Simple, Slash, MD, HTML, Legacy, Headless preset).packages/luthor/src/presets/_shared: shared preset policy, feature guards, mode cache, and style-var helpers.packages/luthor/src/core: toolbar, command palette, slash menu, source view, command registry, shortcuts, and layout helpers.ExtensiveEditor is the base runtime.availableModes.featureFlags.PresetFeaturePolicy when needed.This design keeps behavior centralized while exposing focused preset APIs.
PresetFeaturePolicy merges:
That is why presets like LegacyRichEditor keep metadata-heavy features disabled even when overrides are passed.
ExtensiveEditor supports:
visual-editor: editable visual surfacevisual-only: read-focused visual surface with optional click-to-edit (editOnClick)visual: legacy alias that maps to visual-editorjson, markdown, htmlMode switches validate source input before applying changes.
If conversion fails, an explicit source error is shown and visual content is not silently replaced.
createEditorThemeStyleVars(...) plus CSS custom properties.defaultSettings maps common style values (font, list marker, quote, table, placeholder, code block, toolbar) to CSS vars.CoreEditorCommands.shortcutConfig, with collision and native-conflict guards.apps/web indexes titles, descriptions, body text, and code snippets from every docs page.packages/luthor/src/presets/extensive/ExtensiveEditor.tsxpackages/luthor/src/presets/extensive/extensions.tsxpackages/luthor/src/presets/_sharedpackages/luthor/src/core/commands.ts