LibxaFrame 0.10.0: a stability pass, and PHP 8.5
Not a feature release: the one where the framework got a 197-test suite, and the suite found real bugs in header normalisation, redirect safety, middleware short-circuiting and the Vite manifest.
LibxaFrame 0.10.0 is on Packagist. It is not a feature release: it is the one where the framework got a test suite, and the test suite found things.
197 tests
The suite now covers the container, the HTTP kernel, the router and its pipeline, validation, the Atlas query builder and migrator, sessions, and the encrypter. Writing it was the point; the bugs below are what it turned up.
Header names were not normalised. Request treated Content-Type and
content-type as different headers, so whether a lookup succeeded depended on
what the client happened to send.
Redirects could be pointed off-site. Response now runs a referer through
a safe-referer check before redirecting to it, so a crafted Referer header
cannot turn a back() into an open redirect.
Middleware ordering and short-circuiting. The router, route collection and pipeline all had edge cases where a middleware returning early did not stop the ones after it, which for an auth middleware is the difference between a guard and a decoration.
The Vite manifest emitted duplicates. Two entries sharing a chunk produced
two identical <link> tags. Harmless to look at, wasteful to serve.
Atlas (the query builder, schema and migrator) took the largest share of the fixes, all of them edge cases the new tests provoked rather than anything reported from the wild. That is the value of writing tests for code that already works: you find the cases nobody has hit yet.
PHP 8.5
8.5 is now supported and tested in CI alongside 8.3 and 8.4.
The interesting part of adding a new PHP version is rarely the language changes; it is the toolchain. Dev dependencies had constraints that excluded 8.5 before any of our own code was even parsed, so those had to be widened first. Only then could the real deprecations surface.
The CI matrix runs all three versions on every push, so a change that works on 8.3 and breaks on 8.5 fails before it merges rather than after someone upgrades.
What "0.10" means
The framework is pre-1.0, and follows the convention that the minor version
is the compatibility boundary until it is not. A 0.x bump may change
behaviour; a patch will not.
That is worth saying because 0.10.0 looks like a small step and is not: it is the release where the framework stopped being something that worked when you ran it and started being something with evidence behind it.
Getting it
composer require libxa/framework:^0.10
Or start a new application with the starter kit, which pins a matching version:
composer create-project libxa/libxa my-app