Introduction
system-x is an X11-style desktop framework for Laravel. You describe a window's UI in PHP as a tree of widgets. The framework serialises that tree to JSON and a display server running in the browser renders it. When the user clicks a button or submits a field, the event posts back to PHP, your handler runs, and a fresh tree comes down over a websocket. The browser then morphs its live DOM to match, keeping focus, caret position, selection and scroll intact.
The result is a proper desktop in a browser tab. Windows drag, resize, snap to halves and quarters, maximise and minimise. There's a panel with the open-window list and a clock, a launcher with app folders, per-user theming, and a login greeter. All of it framework-owned: you write apps, not window management.
If you'd rather click around than read, there's a live demo. Everyone gets their own throwaway desktop, so nothing you break matters.
The mental model
If you've written a Livewire component or a React app, the loop will feel familiar, with one difference worth internalising: the server is the single source of truth, and the client echoes no state back.
- Your app class builds a widget tree in
render(). - The framework serialises it and the browser paints it.
- The user interacts. The event posts to the server with the widget id and, for inputs, the live value. Nothing else.
- The framework rebuilds your app, restores its saved state, runs your handler, saves the new state, renders again, and broadcasts the new tree.
- The browser morphs the live DOM toward the new tree. No page reload, no full rebuild, no lost focus.
State lives on your app class as ordinary public typed properties. Anything you declare there is persisted per user and per window automatically. There's no store to configure, no session juggling, and nothing to hydrate by hand.
What's in the box
- A widget toolkit: windows, labels, buttons, text fields, lists, checkboxes, switches, selects, radio groups, sliders, progress bars, badges, tabs, toolbars, dialogs, menus and tooltips.
- A window manager with drag, resize from any edge, snap tiling, maximise, minimise, focus and stacking. Geometry persists per user.
- A desktop shell: panel, launcher with drag-to-group folders, a system menu, theming through the Appearance app, and a branded greeter.
- Durable per-user state, an audit trail of every widget event, and per-app crash isolation, so one broken app can't take the desktop down.
- An SDK for shipping apps and custom widgets as Composer packages.
Where to go next
- Installation gets the package into a Laravel app.
- Building an app covers the app class, durable state, handlers and the widget set. If you read one page, read that one.
- Adding a widget is for when the built-in widgets aren't enough.
- Shipping an app as a package covers distribution.
- The wire protocol documents the contract between the PHP side and the browser, if you want to know how it works underneath.