Installation
Install the package and its Payload peers, and the bundled Lexical admin patch.
On this page
Install @systhemaui/payload together with the Systhema packages it builds on and the Payload peers each project pins itself.
pnpm add @systhemaui/core @systhemaui/react @systhemaui/next @systhemaui/payload
pnpm add -D @payloadcms/next @payloadcms/plugin-import-export \
@payloadcms/plugin-nested-docs @payloadcms/plugin-redirects \
@payloadcms/plugin-seo @payloadcms/richtext-lexical @payloadcms/uiThe peer dependencies above can't be bundled into @systhemaui/payload because PayloadCMS is highly version-sensitive — they install separately so each project pins compatible versions.
For a complete, working setup including Next.js App Router files, see Templates / PayloadCMS.
The Lexical admin patchLink to this section
Systhema ships a pnpm patch against @payloadcms/richtext-lexical inside @systhemaui/cli (node_modules/@systhemaui/cli/patches/). The patch changes no API and no editing behaviour — it collapses redundant schema payloads and sharpens one error message. It lives inside the CLI rather than @systhemaui/payload so it is available before the new @systhemaui/payload is installed in the consumer's node_modules.
The CLI installs it on three paths, all keyed by the same supported @payloadcms/richtext-lexical range:
systhema createadds it to every Payload scaffold.systhema upgradereconciles it in the Dependencies phase, after the peer bumps and before the install: it removes any entry Systhema authored for an older version, copies the bundled.patchinto yourpatches/directory and merges the matchingpnpm.patchedDependenciesentry into yourpackage.json, when the resolved lexical range is one the patch supports. Thepnpm installthatsysthema upgraderuns afterwards applies it.systhema doctorreports a missing, unapplied or stale entry as the fixablelexical-patchcheck (systhema doctor --fixinstalls it), and reports an out-of-range or non-applying installed version without a fix.
What the patch does:
- schemaPath dedup — memoizes
initLexicalFeaturesby(sanitizedEditorConfig, clientFieldSchemaMap, schemaPath)so two nested editors at the same schema location share the same JS object reference for their feature-schema map. React Flight collapses the duplicates to a single$-reference, so a 30-section page that used to ship the same ~1.85 MB schemaMap 29 times now ships it once. - content dedup — after
initLexicalFeaturesbuilds a feature-schema map, the patch walks the map and content-keys-dedupes its values into a per-request pool. A typical Payload schemaMap has ~30 K positions pointing to ~300 distinct field-config arrays — 99 % structural duplicates that React Flight serializes inline because the JS identities differ. The pool rewrites later same-content positions to share the first occurrence's array reference. - actionable block validation errors — upstream reports every failed block write as
block node failed to validate: The following fields are invalid: content, whichever block at whatever depth actually failed. The patch names the block and carries each nested field's own error message up, so a misplaced block deep in a document reads likeBlock "section": the following fields are invalid: content (Block "columns" not found)and points at the real culprit.
On templates/payload, all blocks enabled, the combined effect on /admin/collections/pages/<id> (30-section synthetic page) is ~91 MB → ~21 MB (−77 %), with warm response time roughly halved.
The patch is one-way safe — it never changes the schemaMap shape or field semantics, only collapses byte-identical references and rewords the validation message. When upstream lands equivalent memoization, the codemod can be told to roll the patch back; until then it's the cheapest way to get the wins.
Why the Admin needs itLink to this section
Without the patch, Payload builds each Lexical editor's client field-schema map by prefix-scanning the global schema map, which pulls in every descendant nested editor's block schema. With Systhema's deep nesting (root, region, fragment, slot, and a fragment-stack cycle) that expands combinatorially: a content-heavy page's Admin edit view serialized a payload of about 243 MB, took 15 to 30 seconds to load, and failed with ERR_HTTP2_PROTOCOL_ERROR on deploy. With the patch the payload drops to about 3.6 MB (about 98% smaller), server-render TTFB falls from about 4.5 seconds to about 50ms, and no editing capability is lost.