Tempest 3.0
Tempest 3.0 comes with a new exception handler, several performance improvements, PHP 8.5 support, and more.
Tempest 3.0 is now available, and I want to take a moment to specifically thank all contributors who helped with this release. We've seen a continuous growth in the Tempest community over these past two years, and it's amazing to work with so many talented developers. So thank you all!
Later in this post, I'll list all breaking changes and how to use the automatic upgrader for existing projects. First, I want to highlight some of the awesome new features in Tempest 3.0, you can also read the full changelog here.
New exception handler
Since the very start of Tempest, we relied on Whoops to render our error pages. While it worked, we always envisioned a more modern exception render that was easier to finetune to our needs. With Tempest 3.0 we took the first steps in making this vision a reality.

Props to Enzo for taking the lead on this one. In the future, we want to continue to improve this page, and also further build on it to make debugging Tempest apps even better.
PHP 8.5
I wrote about my vision for only supporting the latest PHP version over a year ago on my personal blog, and this year we're continuing that same trend: Tempest 3.0 only supports PHP 8.5 or higher. The reasons are outlined in detail in that blog post, but the most prominent reasons are these:
- Delaying upgrades only postpones and complicates the work, it never solves any problems.
- I believe in OSS maintainers having a responsibility to push the PHP community forwards.
- We want Tempest to continue to be a modern framework. We can only do that by evolving together with PHP.
CSRF protection changes
We moved away from a classic CRSF-token approach to using Sec-Fetch-Site and Sec-Fetch-Mode. This means that the <x-csrf /> token has been removed and you don't need it anymore.
You can read about the behind-the-scenes in the pull request.
Database improvements
We've done several improvements in the ORM and database components: we worked on performance updates that make our ORM significantly faster; we also support UUIDs as primary columns; and we improved Query::toRawSql() to make debugging complex queries a lot easier.
Closure-based validation
Thanks to PHP 8.5, we can now support closure-based validation:
use Tempest\Database\IsDatabaseModel; use Tempest\Validation\Rules\ValidateWith; final class Book { use IsDatabaseModel; #[ValidateWith(static function (string $value): bool { return ! str_starts_with($value, ' '); })] public string $title; }
Special thanks to Mohammad for adding this!
View improvements
We improved our view parser so that whitespaces are kept as-is. This makes it easier to debug compiled views, and also fixes some edge cases where white-spaces were wrongly stripped away. On top of that, we continued to improve Tempest View's performance, and added support for fallthrough attributes (special thanks to Márk for that one)!
<!-- x-test.view.php --> <div class="test"> <x-slot /> </div> <!-- home.view.php --> <x-test :class="$shouldHighlight ? 'bg-red-100' : ''"> … </x-test> <!-- These attributes will now be merged correctly: --> <!-- <div class="test bg-red-100"> -->
OAuth improvements
Thanks to iamdadmin, our OAuth support now also includes Twitch.
use Tempest\Auth\OAuth\Config\TwitchOAuthConfig; return new TwitchOAuthConfig( clientId: env('TWITCH_CLIENT_ID'), clientSecret: env('TWITCH_CLIENT_SECRET'), redirectTo: [TwitchOAuthController::class, 'callback'], );
We also fixed an annoying bug so that you can automatically run migrations after installing one or more OAuth providers.
Console
Márk also added support for console autocompletion in zsh and bash. It's as easy as running the tempest completion:install command, and you can read more about it here.
Console autocompletion tends to be a tricky one to get right for all systems, so if you run into issues, please let us know.
Breaking changes and automatic upgrades
Since Tempest is still a young framework, breaking changes are to be expected as we polish our codebase. As with the previous major release, we shipped an automatic upgrader, powered by Rector. First, make sure to install Rector in your project if you haven't already:
~ composer require rector/rector --dev # to require rector as a dev dependency ~ vendor/bin/rector # to create a default rector config file
Next, update Tempest; it's important to add the --no-scripts flag to prevent any errors from being thrown during the update.
~ composer require tempest/framework:^3.0 --no-scripts
Then configure Rector to upgrade to Tempest 3.0:
// rector.php use \Tempest\Upgrade\Set\TempestSetList; return RectorConfig::configure() // … ->withSets([TempestSetList::TEMPEST_30]);
Finally, run Rector:
~ vendor/bin/rector # To update all your project files
Unfortunately we weren't able to automate the full upgrade because we're running into some limitations with Rector. In the future, we want to look into alternatives to truly automate the whole upgrade. If you have very extensive Rector knowledge and want to help out, feel free to get in touch via our Discord server or GitHub.
To make sure you don't miss anything, here's a list of all breaking changes with links to their pull requests:
- Deprecated testing utilities were removed
- View and route testing helpers were moved to their correct classes
- Exception handling has been reworked
- Session management and CSRF protection has been reworked
- The
viewfunction has been moved to theTempest\Viewnamespace Arr\map_iterablehas been renamed toArr\map--forcecan now bypassCautionMiddlewareEnvironmentwas made an injectable dependency- Enum events are now supported in the event bus
- Several other core functions have been moved to the correct namespace
- Both LogConfig and DatabaseConfig have been refactored and must be manually updated.
What's next?
We've already started work on a new list of features and fixes for the 3.x release cycle. Some big items coming up are: a dedicated debugging AI, FrankenPHP worker mode support, and a complete overhaul of our event and command bus to make them seriously more powerful. Stay tuned.