Leaf PHP 5, codenamed Morning Glory, introduces a new routing engine and a new error reporter called Leaf Crash. The release arrived on August 15, 2026, and now requires PHP 8.2 or newer.
The main changes include:
- Routes are compiled when they are registered.
- Optional route parameters and inline constraints are supported.
- Leaf Crash replaces the previous error-handling system.
- Group middleware now runs correctly on dynamic routes.
- Raw regular expression routes and the old custom error-handler format no longer work.
Leaf is a modular PHP framework created by Michael Darko. The project began in 2019 and is released under the MIT license.
What Leaf Code Looks Like
A small Leaf application can fit in one file:
<?php require __DIR__ . '/vendor/autoload.php'; app()->get('/', function () { response()->json([ 'message' => 'Hello World!', ]); }); app()->run();
Leaf provides global helper functions such as app() and response(). Other features are available through separate modules that applications can install as needed.
A New Routing Engine
Leaf 5 changes how routes are matched. Earlier versions tested route patterns with regular expressions on every request. Leaf 5 compiles routes when they are registered.
Exact routes are stored in an index for direct matching. Dynamic routes only check the possible matches for that request. This avoids testing every route pattern each time.
Routes can now have optional parameters and inline rules:
/posts/{id?}
/users/{id:[0-9]+}
Named route groups also build on their parent names. A route inside nested admin and users groups can receive a name such as admin.users.index. Resource routes now create their own names as well.
Leaf 5 also adds Router::reset(). It clears routes, hooks, middleware, and saved request state. This is useful for test suites and long-running processes that handle more than one request.
Environment values are now cached for each request. The _env() helper reads from that cache, while _envUncached() performs a fresh read.
Leaf Crash Error Reports
Leaf Crash is the framework's new error-reporting system. Its reports can include:
- Stack frames
- Request details
- Log, view, query, and job breadcrumbs
- Redacted values that should not appear in a report
Development environments receive a detailed debug page. Production environments receive a smaller error page. Leaf uses APP_ENV to choose between them.
Custom error handlers now receive one Leaf\Crash\Report object. In Leaf 4, they received three arguments from Whoops, so existing handlers need to be updated.
Group Middleware Fix
Leaf 5 fixes a bug that could skip group middleware on dynamic routes. It happened when a route such as /{id} was inside a group and global middleware was also present.
The release notes use auth.required as an example of middleware that could be skipped. Applications using Leaf 4 should check grouped dynamic routes that depend on authentication or other request checks.
Another fix corrects base-path detection. Leaf no longer removes URL prefixes when the request is not inside the script's folder. This prevents some 404 errors when using PHP's built-in server or running through the command line.
Upgrade Notes
Leaf 5 includes several breaking changes:
- PHP 8.2 or newer is required.
- Raw regular expression routes no longer match. Paths without
{}placeholders are treated as normal text. Rewrite those routes with named parameters, optional parameters, or inline constraints. - Custom error handlers receive one argument. They now accept a
Leaf\Crash\Reportobject instead of three Whoops arguments. - Exact routes always win. An exact route is chosen before a dynamic route, even if the dynamic route was registered first.
- Async support is paused.
$app->ws()and theeien.enabledsetting have been removed while the Eien server is rebuilt.
To install Leaf 5 in an existing project, use Composer:
composer require leafs/leaf:^5.0
Review route definitions and custom error handlers before upgrading an existing Leaf application.