Headless Architecture (Developer)
Headless Architecture (Developer)
Section titled “Headless Architecture (Developer)”This document defines how @lyfie/luthor-headless is structured, why key design choices exist, and how contributors should extend it safely.
- Keep the package headless and lightweight.
- Keep Lexical integrations in
@lyfie/luthor-headless(not in presets). - Preserve type-safe command/state composition across arbitrary extension sets.
- Support lossless import/export flows (JSON/JSONB).
Runtime Layers
Section titled “Runtime Layers”src/core/*- Editor runtime factory (
createEditorSystem) and context wiring. - Extension factory (
createExtension) for low-boilerplate extension authoring. - Theme contracts and merge helpers.
- Editor runtime factory (
src/extensions/*- Feature modules (formatting, media, core UX, custom nodes).
- Canonical extension type contracts in
src/extensions/types.ts.
src/utils/*- Runtime utility surface for JSON/JSONB-first integrations.
Why the extension model looks this way
Section titled “Why the extension model looks this way”- Extension arrays are declared
as constso TypeScript can infer literal extension names and produce precise command/state types. createEditorSystem<Extensions>()extracts and merges command/state query types from every extension.BaseExtensionandcreateExtensionboth exist:BaseExtension: best for complex, stateful, class-style extensions.createExtension: best for straightforward extensions without class boilerplate.
Lifecycle and composition
Section titled “Lifecycle and composition”- Extensions can provide:
getNodes()for Lexical nodesgetPlugins()for React pluginsgetCommands()for mutation APIsgetStateQueries()for async active state checksonInitialize()for setup/cleanup
createEditorSystemcomposes these contributions and resolves collisions deterministically through extension order and initialization priority.
Import / export strategy
Section titled “Import / export strategy”- JSON remains the source-of-truth round-trip format for exact editor state.
- JSONB is the recommended persistence target for production databases.
Contribution rules for this package
Section titled “Contribution rules for this package”- Keep dependencies minimal; optional integrations must degrade gracefully when absent.
- Place any Lexical-derived feature logic in
packages/headlessand re-export from presets. - Keep extension APIs explicit and strongly typed.
- Favor additive extension configs over hidden global behavior.