Skip to content
Projects

Flagship engineering project

Serixa

Widget composition for server-rendered PHP

An open-source Flutter-inspired PHP UI framework for building server-rendered applications using reusable PHP widgets and a widget-tree architecture. It emits semantic HTML, compiles CSS from themes and design tokens, and can load a small progressive-enhancement runtime when interactivity is needed.

PHPOpen SourceWidget TreeSSRComposerPackagistCSS CompilerDesign System

Architecture

PHP widgets → HTML / CSS pipeline

Hover or focus a stage · not Laravel / not a SPA

Overview

Composition feels familiar if you have used Flutter or React components, but the tree is rendered on the server in PHP. Serixa owns the UI layer - widgets, HTML, themes, and optional progressive enhancement. Applications still own routing, persistence, and authentication.

Motivation

The problem with traditional PHP templating

PHP UI work often drifts into string templates, partials, and one-off CSS. When teams want Flutter- or React-style composition, they usually adopt a JavaScript SPA - even for pages that could stay server-rendered.

Why Serixa was created

Serixa keeps composition in PHP. Layouts, text, buttons, forms, and cards are objects in a tree. The framework owns HTML generation, theme class maps, offline CSS compilation, and optional progressive enhancement. Routing, persistence, and auth stay outside core on purpose.

Serixa is not a full-stack application framework. Core has no router, ORM, auth system, sessions, or job queue. Embed widgets in an existing PHP app, or scaffold a thin shell and bring your own backend.

Widget tree architecture

  1. 1

    Developer

    Describe UI in PHP only

  2. 2

    PHP widgets

    Button, Card, Column, Row, ...

  3. 3

    Widget tree

    WidgetTree materialised from the root

  4. 4

    Render pipeline

    BuildTree → ResolveContext → Lifecycle → Theme → Accessibility → Render

  5. 5

    Semantic HTML

    Fragments or full Document pages

  6. 6

    Theme Compiler

    Tokens and recipes → /assets/serixa.css

  7. 7

    Browser

    HTML + CSS; optional ~21 KB serixa.js runtime

Default render passes

BuildTreePassResolveContextPassLifecyclePassThemeResolutionPassAccessibilityPassRenderPass

How widgets become HTML

App widgets enter Renderer. Full pages go through DocumentRenderer. Fragments run the ordered RenderPipeline, then HtmlWriter emits the HTML string. Themes resolve class maps before render. Accessibility passes run before the final HTML write.

Serixa architecture layers

Theme system, design tokens, CSS compilation

Theme system

Themes map semantic props such as primary() and large() to class names. Custom themes implement ThemeInterface and can replace DefaultTheme.

Design tokens

Token types cover colour, spacing, radius, shadow, typography, border, opacity, z-index, breakpoints, and transitions under Serixa\Token\.

CSS compiler

ThemeCompiler and StyleCompiler produce offline CSS. serixa build writes /assets/serixa.css. There is no Tailwind Play CDN dependency.

Component composition

Developers build UI without manually writing HTML for the common cases. Layout and content widgets nest like Flutter widgets or React components, then render to real HTML elements.

Container

Constrains width and wraps a child subtree (for example maxWidth('md')).

Column / Row

Flex layouts for vertical or horizontal composition with gap and alignment helpers.

Text

Typography widget with tone helpers such as muted, instead of raw paragraph markup.

Button

Semantic button with primary/secondary/danger/ghost, sizes, and optional DOM events.

Card

Article-like surface with title and nested children for grouped content.

Scaffold / AppBar

Application chrome for shell layouts (app bar, sidebar, body, footer).

Example widget code

use Serixa\Component\Button;
use Serixa\Component\Card;
use Serixa\Component\Center;
use Serixa\Component\Column;
use Serixa\Component\Container;
use Serixa\Component\SizedBox;
use Serixa\Component\Text;
use Serixa\Rendering\Renderer;

$ui = Container::make(
 Center::make(
 Column::make([
 Card::make()
 ->title('SERIXA')
 ->child(
 Text::make('Write PHP. Get semantic HTML.')
 ->tone('muted'),
 )
 ->child(SizedBox::height(4))
 ->child(
 Button::make('Get started')
 ->primary()
 ->large(),
 ),
 ])->alignCenter()->gap(4),
 ),
)->maxWidth('md');

echo (new Renderer())->render($ui);

Button::render() emits a real <button> with theme classes and escaped label text. Card renders an <article> with an optional header. Layout widgets wrap children via the active theme. Exact class strings come from DefaultTheme / ThemeCompiler recipes such as .sx-btn-primary.

<!-- Shape produced by the widget renderers (theme classes abbreviated) -->
<div class="...container...">
 <div class="...center...">
 <div class="...column...">
 <article class="...card...">
 <header><h2>SERIXA</h2></header>
 <p class="...muted...">Write PHP. Get semantic HTML.</p>
 <button type="button" class="... sx-btn-primary ...">Get started</button>
 </article>
 </div>
 </div>
</div>

Source example: framework/examples/basic.php in the Serixa monorepo.

What Serixa includes

Widget-tree pipeline

UI is a tree rooted at WidgetInterface. BuildTreePass materialises WidgetTree before lifecycle, theme, accessibility, and render passes run.

Reusable PHP widgets

Concrete widgets live under Serixa\Component\ - Button, Card, Text, Container, Row, Column, forms, data display, and interactive overlays.

Server-side rendering

Each request returns an HTML string. There is no virtual DOM and no hydration loop.

PHP-first authoring

Common UI is expressed as method chains such as Button::make('Save')->primary()->large() instead of hand-written markup for every control.

HTML generation

Renderer coordinates DocumentRenderer for full pages, or RenderPipeline with HtmlWriter for fragments.

Themes and design tokens

Themes map semantic props to classes. Tokens cover colour, spacing, radius, shadow, typography, and related design axes.

Offline CSS compilation

ThemeCompiler / StyleCompiler build CSS ahead of time. serixa build writes /assets/serixa.css. Production does not depend on a Tailwind Play CDN.

Layout primitives

Row, Column, Center, Padding, Spacer, Expanded, SizedBox, Stack, Divider, Scaffold, plus chrome widgets such as AppBar and Sidebar.

Optional progressive enhancement

serixa.js (~21 KB on disk) binds data-serixa-on-* hooks for modals, drawers, tabs, and toasts. Static pages need no JavaScript.

Composer packages and CLI

Production package is serixa/framework. serixa/cli scaffolds pages and themes, and runs build, doctor, inspect, and profile for local DX.

Docs and ADRs

Architecture notes, getting started, styling, progressive enhancement, and ADRs covering the render pipeline, namespaces, and API stability - with the public site at serixa.yasaboy.com.

Folder structure

SERIXA/
 framework/ # serixa/framework (production package)
 packages/ # Optional packages (icons, charts, forms, admin, cli, ...)
 starters/ # Starter kits
 playground/ # Local demos
 docs/ # Architecture, ADRs, guides
 website/ # SSR documentation website
 tools/ # Build / release helpers
 validation/ # Real-app validation fixtures

Package ecosystem and CLI

  • serixa/framework - production PHP UI framework package
  • serixa/cli - scaffolding, build, doctor, inspect, profile
  • serixa/icons, charts, calendar, forms, admin, auth-ui, devtools - official UI kits

CLI commands documented for local DX include new, make:page / make:component / make:theme, build, doctor, inspect, profile, and related helpers. The CLI is a development tool, not part of the request path.

Documentation

Architecture docs, getting started, styling, progressive enhancement, CLI guides, and ADRs live in the monorepo. The official public docs site is live at https://serixa.yasaboy.com.

Performance

  • Documented local benches (PHP 8.2, machine-variant): ThemeCompiler on the order of milliseconds for small rule sets; Renderer averages tens of milliseconds over small widget trees in the v1 performance notes.
  • Client runtime file size is about 21 KB on disk for serixa.js.
  • These numbers are local measurements, not guarantees for every host.

Timeline

  1. M1-M2Rendering core, widgets, layout primitives, theme maps
  2. M3-M5Widget tree, lifecycle, render pipeline, document/asset engine, ADRs
  3. M6-M9UI foundation, data display, progressive enhancement, interactive widgets
  4. v1.0.0Public GitHub release; Packagist package serixa/framework; documentation site at serixa.yasaboy.com

Lessons learned

  • Keeping Serixa a UI layer - not a full-stack application framework - makes the product easier to explain and safer to embed in existing PHP apps.
  • Offline CSS compile belongs in the default path so production does not depend on a CDN play build.
  • ADRs and an explicit public API surface help a framework-shaped monorepo stay coherent as packages grow.
  • Progressive enhancement should stay optional: static widget pages must work with zero JavaScript.

Future roadmap

  • Public documentation is live at https://serixa.yasaboy.com.
  • Work still ahead of core includes deeper form-validation adapters, focus-trap hardening, optional community templates, and marketplace-style adapters that stay out of the core package.
  • Additional starter kits beyond the current set are planned as later ecosystem work, not claimed as shipped products here.

Honest boundaries

  • Not a Laravel or Symfony replacement - no router, ORM, auth, or queue in core.
  • Not React - no virtual DOM, hydration, or client widget re-render loop.
  • auth-ui and similar packages are presentation-oriented; applications still own real sessions and security.
  • Optional ecosystem packages vary in maturity; the portfolio leads with the framework, CLI, docs, and core UI story.

Downloads