Framework12 min readNot archived on GitHub

Leaf: a lightweight PHP framework

A guide to Leaf, a PHP framework built to stay light: what it is, how requests run, how to start a small app, and what the official docs leave unknown.

PHP compatibility and project lifecycle

The Leaf docs state PHP 8.2 or higher and Composer, with the Leaf CLI optional. PHP 8.4 meets that floor but is not confirmed as tested; PHP 8.5 compatibility is unknown. Version, licence and support status are unknown from the supplied source.

Official sources checked 2026-10-22. Browser lessons on this site run PHP 8.5.

Sources and evidence limits

It relies only on the official Leaf documentation page listed under sources. Where that page is silent, this guide says the answer is unknown.

What Leaf is

Leaf is a PHP framework. The docs describe it as designed to stay light while offering production-ready pieces when you need them. It is not a PHP runtime and not an alternative interpreter. It is also not a CMS. A framework gives you routing, request and response handling, and optional packages. A CMS product such as Drupal ships an editorial interface, content storage and a permission model. Drupal is a CMS built on PHP, and PHP core is the language engine underneath both. Leaf sits in the first group: you write PHP, and Leaf organizes how requests reach your code.

The same care applies to runtimes. Swoole and Open Swoole are different projects, so never assume that documentation or extension behavior for one applies to the other. The Leaf page does not mention either, so this guide makes no claim about running Leaf on them.

Architecture and package model

The docs describe a small core plus optional add-ons. You begin with the smallest app and then install only what the project needs. Packages come from two documented routes: the Leaf CLI with a leaf install command, or Composer with a leafs vendor prefix. The page names the package slot generically, and the exact name of the core package is not given in the supplied source, so confirm it in the official docs before installing.

The docs list these capability areas:

  • Routing and middleware: endpoints, groups, dynamic routes and request flow.
  • Protection: login, signup, JWT, CSRF, headers, encryption, sessions and protected routes.
  • Data: a query builder, models, Redis, files, validation and migrations.
  • Agent-friendly context: conventions kept visible for AI-assisted work.

The page does not say which of these ship in the core and which are separate packages. Treat that as unknown until you read the package documentation.

Execution model

The smallest documented app loads the Composer autoloader, registers a GET route on the root path that returns JSON, and then calls run. That shape suggests a classic request lifetime: PHP starts, your entry file runs, the framework matches a route, a response is sent, and request state is discarded. The page does not state this outright, and it does not document any persistent-worker mode, so whether Leaf supports one is unknown.

The distinction matters. In a classic lifetime, such as PHP-FPM or the built-in development server, each request starts clean. In a persistent worker, one PHP process handles many requests. Persistent workers can leak state: static properties, singletons, container instances, open database connections, authenticated user data, session or cookie data and cached request objects can survive into the next request. The result may be one user seeing another user's data. Cleanup is the application's responsibility: reset or rebuild per-request objects, avoid mutable globals, close or validate connections, clear user identity after every response, and test that two consecutive requests cannot see each other's state. Do not run Leaf under a persistent worker until you have evidence from official documentation that it is supported and how it resets state.

Practical use cases

The docs describe three paths:

  • Micro-tools: ideas, experiments, small utilities that should stay understandable.
  • Web apps: Leaf MVC for startups, internal tools and dashboards that need a clear structure.
  • APIs: backend endpoints for React, Vue, mobile apps, automation tools and agent workflows.

For learners, the micro-tool path is the best first step, because the whole app is one file and one route.

Installation approach

The documented requirements are PHP 8.2 or higher and Composer, with the Leaf CLI optional but recommended. Our learning track uses PHP 8.4 with PHP 8.5 planned. PHP 8.4 satisfies the stated minimum, but the docs do not list tested minor versions, so full compatibility with 8.4 or 8.5 is unconfirmed. The docs suggest Laravel Herd, php.new or XAMPP if you lack a local PHP setup.

The example below follows the plain Composer workflow. It uses the documented smallest app and PHP's built-in development server bound to 127.0.0.1. The built-in server is a PHP feature, not something the Leaf page documents, and it is suitable only for local learning.

Strengths

  • A very small starting point: one route and one run call.
  • Incremental dependencies, so you add only what you need.
  • A documented set of auth, security and data tools when the app grows.
  • Two install routes: CLI or plain Composer.

Limitations and unknowns

  • Lifecycle is unknown: the page gives no version, release or support status.
  • Exact PHP 8.4 and 8.5 compatibility is not documented beyond the 8.2 minimum.
  • The licence is not stated in the supplied source.
  • Performance is not measured or compared in the source, so this guide makes no speed claims.
  • Persistent-worker support, state reset behavior and the internal container design are undocumented here.
  • Production deployment steps are not covered by the supplied page.
  • Runtime examples need Composer and network access to download packages, so they are not browser exercises.

Deployment notes

The source gives no deployment instructions, so consult the official documentation for hosting guidance. As general PHP practice, a classic deployment puts a web server in front of PHP-FPM with a single public entry point. Never expose FastCGI or PHP-FPM ports to the public internet; keep them on a private socket or loopback interface. Keep secrets out of source control and out of example files.

Links

The official Leaf documentation is the only source used for this guide. Check it for current package names, versions and deployment advice.

Practical examples

These examples have not been run in a live environment yet. Commands and versions follow the official documentation linked on this page; check them before relying on them, and report a problem if one does not work.

Smallest Leaf app with Composer and the PHP built-in server

A minimal project using the documented smallest Leaf app: one GET route returning JSON. It uses Composer and PHP's built-in development server on loopback only. The core Leaf package name is not given in the supplied source, so it must be confirmed in the official docs and substituted for the placeholder before running.

composer.json

{
  "name": "learnphponline/leaf-hello",
  "description": "Minimal Leaf hello world",
  "type": "project",
  "require": {
    "php": ">=8.2"
  }
}

index.php

<?php

require __DIR__ . '/vendor/autoload.php';

app()->get('/', fn () => response()->json([
    'message' => 'Hello World!'
]));

app()->run();

Install and run

php -v
composer install
composer require leafs/<package-name>
php -S 127.0.0.1:8000 index.php
curl http://127.0.0.1:8000/

Expected behavior

If the correct Leaf package is installed, the server listens on 127.0.0.1:8000 only, and a GET request to the root path should return JSON containing the message Hello World!.

Replace <package-name> with the core package name from the official docs; it is not stated in the supplied source. The built-in server is for local learning only, not production. Leaf's routing and response helpers are used exactly as shown in the docs, with no other API assumed. Requires Composer and network access, so it is not a browser exercise.