Skip to content

Kévin Dunglas

Founder of Les-Tilleuls.coop (worker-owned cooperative). Creator of API Platform, FrankenPHP, Mercure.rocks, Vulcain.rocks and of some Symfony components.

Menu
  • Talks
  • Resume
  • Sponsor me
  • Contact
Menu

Merry Christmas! FrankenPHP 1.11: Hot Reload, Structured Logging, and More Speed

Posted on December 24, 2025December 24, 2025 by Kévin Dunglas

Ho ho ho! 🎅

I’m thrilled to announce the immediate availability of FrankenPHP 1.11!

We have a special gift for the PHP community to unwrap this Christmas Eve. This release is laser-focused on improving the Developer Experience (DX) and deepening the integration between PHP and the Go ecosystem.

Here is what we put under the tree this year.

🎁 Built-in Hot Reload

This is the feature many of you have been putting on your wish lists. FrankenPHP 1.11 introduces a native hot reload capability designed to vastly improve your development workflow.

Forget mashing F5. This feature provides an experience similar to the Hot Module Replacement (HMR) found in modern JavaScript tooling. When you save a PHP file (or a template, or an asset…), FrankenPHP detects the change and updates the browser in real-time.

It leverages FrankenPHP’s built-in Mercure hub to push updates instantly. A support JavaScript library, built on top of the excellent Idiomorph library, will intelligently “morph” the DOM, preserving your scroll position and form input state.

This feature natively works with WordPress (showcased in the video), Laravel, Symfony, and virtually any PHP application.

How to use it

Enable the hot_reload option in your Caddyfile.

Warning: This feature incurs performance overhead as it watches the filesystem. Never enable it in production.

localhost

# Enable the built-in Mercure hub
mercure {
    anonymous
}

root public/
php_server {
    # Enable the hot reload feature
    hot_reload
}

For the best experience, if your app or framework supports the worker mode, combine it with the worker.watch directive. This ensures your worker script kernel restarts while the browser simultaneously updates:

localhost

mercure {
    anonymous
}

root public/
php_server {
    hot_reload

    worker {
        file /path/to/my_worker.php
        watch
    }
}

On the client side, just add the necessary JS libraries and meta element to your layout. The Mercure URL is automatically provided via $_SERVER['FRANKENPHP_HOT_RELOAD'].

<!DOCTYPE html>
<title>FrankenPHP Hot Reload</title>
<?php if (isset($_SERVER['FRANKENPHP_HOT_RELOAD'])): ?>
<meta name="frankenphp-hot-reload:url" content="<?=$_SERVER['FRANKENPHP_HOT_RELOAD']?>">
<script src="https://cdn.jsdelivr.net/npm/idiomorph"></script>
<script src="https://cdn.jsdelivr.net/npm/frankenphp-hot-reload/+esm" type="module"></script>
<?php endif ?>

🎄 Structured Logging with frankenphp_log()

Observability in modern applications is crucial. Go recently introduced standardized structured logging via the log/slog package, and we are bridging this capability into PHP.

The new frankenphp_log() function allows you to emit structured logs directly from your PHP code.

This is fantastic for production environments, as your PHP logs will now be formatted consistently with Caddy’s logs, making ingestion into platforms like Datadog, Grafana Loki, or Elastic, as well as OpenTelemetry support, much easier.

<?php

frankenphp_log(
    message: "User logged in",
    level: FRANKENPHP_LOG_LEVEL_INFO, // FRANKENPHP_LOG_LEVEL_DEBUG, FRANKENPHP_LOG_LEVEL_INFO, FRANKENPHP_LOG_LEVEL_WARN, or FRANKENPHP_LOG_LEVEL_ERROR, defaults to FRANKENPHP_LOG_LEVEL_INFO
    context: [
        "user_id" => 123,
        "ip" => $_SERVER['REMOTE_ADDR']
    ]
);

By default, as Caddy is configured to output structured JSON logs, this PHP call will produce a beautifully structured log entry in standard output:

{"level":"info","ts":1703690000.123,"logger":"frankenphp","msg":"User logged in","user_id":123,"ip":"192.168.1.1"}

Logging can be entirely customized using Caddy configuration.

🛷 Performance Improvements

FrankenPHP is already known for being fast but we want it to fly like a reindeer.

Thanks to rigorous benchmarking (with the help of Tideways), we identified and resolved bottlenecks under very high load. This results in better overall throughput in edge cases and, more importantly, improved tail latency (p95 and p99 benchmarks). Your application will be more consistent under heavy load.

We also significantly improved the performance of uncommon HTTP headers parsing by upgrading to version 2 of the Otter cache library.

Thanks to these patches, according to our benchmarks, FrankenPHP is now faster than PHP-FPM even without enabling the worker mode.

🧸 Unwrap “Le Monstre”

What is Christmas without toys?

FrankenPHP elePHPant

We are delighted to announce that the official FrankenPHP plushy—affectionately known as “Le Monstre”—is finally ready for adoption!

For now, availability is exclusive to those who attended the API Platform Conference last September. If you were there, head over to Le Monstre shop and use your conference ticket number as the coupon code to unlock the checkout and claim your plushy.

For everyone else, don’t worry! Le Monstre will be available to the general public in early 2026.

Get it now!

I want to thank all the contributors who helped make this release possible. I hope you enjoy this release as much as we enjoyed building it.

Merry Christmas and Happy New Year from the FrankenPHP team! 💜

Download FrankenPHP v1.11

Related posts:

  1. The PHP Revolution Is Underway: FrankenPHP 1.0 Beta
  2. HTTP/2: speed up your apps and dispatch real time updates (Symfony and API Platform’s features announcement)
  3. FrankenPHP has reached 10,000 stars: the elePHPant plush toy is coming!
  4. Develop Faster With FrankenPHP

Leave a ReplyCancel reply

Social

  • Bluesky
  • GitHub
  • LinkedIn
  • Mastodon
  • X
  • YouTube

Links

  • API Platform
  • FrankenPHP
  • Les-Tilleuls.coop
  • Mercure.rocks
  • Vulcain.rocks

Subscribe to this blog

Top Posts & Pages

  • FrankenPHP: The Modern Php App Server, written in Go
  • Symfony's New Native Docker Support (Symfony World)
  • Securely Access Private Git Repositories and Composer Packages in Docker Builds
  • FrankenPHP has reached 10,000 stars: the elePHPant plush toy is coming!
  • JSON Columns and Doctrine DBAL 3 Upgrade
  • FrankenPHP’s New Features: Thread Autoscaling, Mostly Static Binaries, deb and RPM Packages, Caddy 2.10…
  • Connection to a MS SQL Server from Symfony / Doctrine on Mac or Linux
  • Develop Faster With FrankenPHP
  • Dapper retardé de 6 mois
  • PHP and Symfony Apps As Standalone Binaries

Tags

Apache API API Platform Buzz Caddy Docker Doctrine FrankenPHP Go Google GraphQL HTTP/2 Hydra hypermedia Hébergement Javascript JSON-LD Kubernetes La Coopérative des Tilleuls Les-Tilleuls.coop Lille Linux Mac Mercure Mercure.rocks Messagerie Instantanée MySQL performance PHP Punk Rock Python React REST Rock'n'Roll Schema.org Security SEO SEO Symfony Symfony Live Sécurité Ubuntu Web 2.0 webperf XML

Archives

Categories

  • DevOps (85)
    • Ubuntu (68)
  • Go (20)
  • JavaScript (46)
  • Mercure (7)
  • Opinions (91)
  • PHP (176)
    • API Platform (80)
    • FrankenPHP (14)
    • Laravel (1)
    • Symfony (97)
    • Wordpress (6)
  • Python (14)
  • Security (15)
  • SEO (25)
  • Talks (46)
© 2025 Kévin Dunglas | Powered by Minimalist Blog WordPress Theme