01 / THE PROBLEM
Traditional CMS is a developer nightmare.
You didn't sign up to fight your tools. But here you are — three days deep in a plugin that should've taken an afternoon.
Need a custom block? Build a plugin.
WordPress forces you into a PHP plugin architecture just to add a simple repeatable section. What should be a component is now a registered post type, a meta box, and 200 lines of boilerplate.
Your content is theirs, not yours.
Schemas live in the database, not in your codebase. Switch CMS and you're migrating everything manually. There's no local dev story, no version control, no git history for content structure.
Every plugin is a performance tax.
A fresh WordPress install with 10 plugins routinely scores sub-60 on PageSpeed. You spend more time optimizing bloat than building features — and the client still asks why the site is slow.
43% of the web. 90% of the CVEs.
Outdated plugins, exposed wp-admin, SQL injection via poorly written themes — maintaining WordPress in production means babysitting a security checklist indefinitely.
Your components live in two places.
The frontend is React. The CMS is PHP. The schema is in a MySQL table. Nothing is co-located, nothing is typed, and onboarding a new dev means explaining a system that makes no architectural sense.
Built in 2003. Feels like it.
No TypeScript, no hot reload, no modern tooling. Gutenberg tried to modernize but layered React on top of a PHP monolith — the worst of both worlds, not the best.
Lyrix is the alternative.
02 / HOW IT WORKS
Blocks are code. Pages are data. Rendering is yours.
No proprietary APIs. No abstraction layers. Just React components, typed JSON, and full control over rendering.
Define blocks as React components
No PHP. No proprietary templating. A block is just a typed React component — lives in your codebase, versioned with git, works with your design system.
// functions.php
register_post_type('hero_block', [...]);
add_meta_box(
'hero_fields', 'Hero Fields',
'render_hero_meta', 'hero_block'
);
// + 200 more lines...import { defineBlock } from 'lyrix/blocks'
export const HeroBlock = defineBlock({
name: 'Hero',
schema: {
title: { type: 'string' },
subtitle: { type: 'string' },
},
render: ({ title, subtitle }) => (
<section>...</section>
)
})Visual composition outputs typed JSON
Editors build pages visually in Lyrix Studio. Under the hood it's a JSON array of blocks — typed, yours, stored wherever you want.
// what your app receives
{
blocks: [
{ type: "Hero", data: { title: "Welcome", subtitle: "..." } },
{ type: "Features", data: { items: [...] } },
{ type: "CTA", data: { label: "Get Started" } },
]
}You own the entire render lifecycle
No hidden magic. Fetch the JSON, map over the blocks, render your components. That's the entire system.
// page.tsx — the entire rendering pattern
const { blocks } = await getPage(slug)
const registry = { HeroBlock, FeaturesBlock, CTABlock }
return blocks.map(({ type, data }) => {
const Block = registry[type]
return <Block key={type} {...data} />
})You control SSR vs SSG, caching, styling, error boundaries — everything. Lyrix never touches your render output.
03 / IN PRACTICE
A block is just a component.
- Strongly typed props from JSON schema.
- Zero proprietary wrappers or APIs.
- Full access to your styling system.
"Developers should own their content structure as much as they own their code."
— Lyrix Philosophy
04 / WHAT'S COMING
The roadmap.
Lyrix is in early development. Here's what's shipping and what's next.
- App Router support
- Block registry & runtime renderer
- JSON-based serialization
- Visual page editor
- Drag & drop block composition
- Live preview
- Plugin system
- Playground & examples
- Block marketplace






