Tempest 2.0

We've just tagged Tempest 2.0. It's a release focussed on fine-tuning and fixing lots of details. It also signifies that we're committed to Tempest, we're in this for the long run!

by Brent on September 16, 2025

As we've said from the start: our aim is to make upgrades with Tempest as smooth as possible. Breaking changes are bound to happen in any project in this stage, and we want to burden our users as little as possible. That's why we added an easy, automated way which handles the upgrade to Tempest 2.0 for you. It should only take five minutes.

Tempest upgrades are handled via Rector. So before doing anything else, make sure Rector is installed in your project:

~ 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:^2.0 --no-scripts

Then you should add the Tempest set to your Rector config file:

// rector.php

use \Tempest\Upgrade\Set\TempestSetList;

return RectorConfig::configure()
    // …
    ->withSets([TempestSetList::TEMPEST_20]);

Then run the following commands

~ vendor/bin/rector # To update all your project files
~ ./tempest discovery:clear # Which is needed to make sure discovery cache is updated
~ ./tempest key:generate # To generate a new signing key and should be done for every environment
~ ./tempest migrate:rehash # To rehash all migrations, which internal workings were changed with this release

Finally, review and test your project and make sure to read through the list of the breaking changes below. The changes in bold are automated by Rector, the other ones are internal changes that should — in theory — have no effect. Yet we wanted to mention them for transparency's sake.

  • #1458: Tempest\Database\Id is now called Tempest\Database\PrimaryKey.
  • #1458: The value property of Tempest\Database\PrimaryKey has been renamed from id to value.
  • #1507: Tempest\CommandBus\AsyncCommand is now called Tempest\CommandBus\Async.
  • #1444: Validation rule names were updated.
  • #1513: The DatabaseMigration interface was split into two.
  • \Tempest\uri and \Tempest\is_current_uri are both moved to the \Tempest\Router namespace.
  • You cannot longer declare view components via the <x-component name="x-my-component"> tag. All files using this syntax must remove the wrapping <x-component tag an#1439: d instead rename the filename to x-my-component.view.php. This was an undocumented feature and likely not used by anyone.
  • #1447: Cookies are now encrypted by default and developers must run tempest key:generate once per environment.
  • #1435: Changes in view component variable scoping rules might affect view files.
  • #1444: The validator now requires the translator, and should always be injected instead of manually created.

Apart from these breaking changes, Tempest 2.0 also includes a range of bug fixes, internal refactors, and a handful of new features. You can read the full release notes here.

What's next?

There are many more things to work on. My personal focus for now will be to get FrankenPHP's worker mode support built-into Tempest. We're also working on a proper PhpStorm plugin for Tempest View, and Enzo's focus will be on a debugging UI, as well as asynchronous transport features. Exciting times ahead!

Finally, if you're interested in trying Tempest out or in contributing, make sure to join our Discord, where by now over 500 developers are gathered to work with and talk about Tempest.

Troubleshooting

One issue you might run into during deployment are outdated discovery caches. You should be able to run tempest discovery:clear, but if for some reason that doesn't work, you can always manually remove your cache folder: rm -r .tempest/cache/.

If you happen to encounter such an issue, please let us know on Discord or via GitHub.