A sunset notice
What if you never had to
leave PHP?
That was Leaf UI's pitch, and Leaf 5 still keeps the promise. The Leaf UI library itself is retired, so here is where its job went, each one link away. The honest story of the retirement is further down.
leaf view:install --tailwind
Blade docs →
leaf view:install --react
Inertia docs →
leaf scaffold:auth
Scaffolds →
npm create hana-app
Hana JS →
Came here for the history instead? The honest story of Leaf UI's retirement starts below.
The itch we were scratching
Making a button update a counter used to mean two languages, an API endpoint, a fetch call, and a state library, all to move one number. If PHP was where you thought, every interactive feature dragged you out of your own head. We wanted the whole loop in one place:
use Leaf\UI\Component; class Counter extends Component { public $key = 'Counter'; public $count = 0; public function increment() { $this->count += 1; } public function render() { return " <button @click=\"increment\">+</button> <span>{$this->count} clicks</span> "; } }
No API layer, no context switch, one language. And honestly, it worked. Leaf UI shipped real interfaces, and the people who used it loved what it stood for.
Then the problem dissolved
Two things changed since Leaf UI was born, and neither of them was Leaf UI's fault.
The frontend ecosystems matured, and Leaf built proper bridges instead. Blade covers server-rendered views with barely any ceremony. Inertia connects Leaf to React, Vue and Svelte, and the API layer that usually sits in between never gets written. A PHP-only reactive layer was never going to catch the documentation and tooling those stacks get for free, so leaf view:install hands them to you in one command.
AI-assisted development removed the itch itself. "Build interfaces without leaving PHP" mattered most when leaving PHP meant a real learning curve. Your assistant already writes fluent React, Vue, Svelte and Blade, and Leaf 5's project context keeps that output aligned with your app. Staying inside PHP used to be the shortcut. These days the real shortcut is picking tools the rest of the world tests and maintains for you.
Maintaining a reactive component framework is an enormous job. We would rather pour that energy into the core, the modules and the tooling that make Leaf what it is. Retiring Leaf UI is not us giving up on the idea. It is us admitting the idea won: interactivity without ceremony is now everywhere, so a separate framework for it has nothing left to solve.
What to use instead
Depending on what you used Leaf UI for:
| If you were building | Reach for |
|---|---|
| Server-rendered pages and forms | Blade (default in Leaf MVC), optionally with Tailwind |
| Reactive, component-driven UIs | Inertia + React, Vue or Svelte via leaf view:install --react / --vue / --svelte |
| Complete features (auth pages, landing pages, waitlists) | Scaffolds: leaf scaffold:auth, leaf scaffold:landing-page, leaf scaffold:waitlist |
| Small interactive islands on server-rendered pages | Blade + a sprinkle of vanilla JS or the lightweight library of your choice |
If you have Leaf UI in production
The repositories are archived on GitHub: no new features, fixes or security patches will land. Leaf UI was never part of Leaf MVC's default setup, so most Leaf 5 apps are unaffected.
If you have a production app built on Leaf UI, plan a migration to one of the stacks above. Scaffolds are the fastest way over, since they drop working Blade or Inertia pages into your app for you to reshape, which beats staring at a blank file. And if you get stuck anywhere, come find us on Discord. We have helped people plan bigger moves than this one.
A thank you
Leaf UI taught us a lot about what Leaf developers actually want, and pieces of its DNA live on in the scaffolds and the view system. Thank you to everyone who built with it, filed issues and contributed code. Retiring a project we loved is easier knowing the ideas survive in better homes.