Open-source project
livewire/blaze avatar
livewire/blaze

Blaze compiles Blade components into plain PHP functions

Pre-compile Blade components for blazing fast rendering performance

751 stars39 forksPHPMIT

At a glance

What is it?
Blaze is a Livewire package for Laravel that pre-compiles anonymous Blade components into optimised PHP functions, so a component render skips the usual Blade pipeline. The trade is a long list of unsupported features, including class-based components and view composers, that has to be checked against your own templates.
Who is it for?
Blaze suits a Laravel application with a large set of anonymous Blade components and a performance budget that the standard rendering pipeline is eating, and it suits teams that render the same component thousands of times, such as icon and avatar lists.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A drop-in replacement for anonymous components, with caveats

Blaze is a Livewire package for Laravel whose stated purpose is to speed up your app with optimized Blade component rendering. The pitch out of the box is a drop-in replacement for anonymous Blade components that requires no changes to your existing code, and the mechanism is compiling your templates into optimized PHP functions instead of using the standard rendering pipeline, which the README says eliminates 91 to 97 percent of the overhead while maintaining near full feature parity with Blade. Near full is doing real work in that sentence, and the limitations section later in the README is where the gaps are spelled out. The intended user is a Laravel developer with a template layer that renders a lot of components, which in practice means an application with a design system rather than one with a dozen views.

The benchmark is a loop of 25,000 components, not a page load

The headline figure in the README is a bar chart of 25,000 anonymous components rendered in a loop, 500ms without Blaze and 13ms with it, and the detailed table breaks that down by scenario. No attributes goes from 500ms to 13ms, a 97.4 percent reduction. Attributes only goes from 457ms to 26ms. Attributes with merge() goes from 546ms to 44ms. Props plus attributes goes from 780ms to 40ms. The default slot goes from 460ms to 22ms, named slots from 696ms to 49ms, and a nested @aware case from 1,787ms to 129ms, which is the largest absolute number in the table and also the largest saving. The README adds the caveat that these numbers reflect rendering pipeline overhead, so if your templates perform expensive operations internally, that work still affects performance. That is the honest framing: Blaze removes framework overhead, not your own work.

Two ways to enable it, one per component or per directory

There are two ways to turn Blaze on, and the README recommends starting small. The first is the @blaze directive added to the top of an individual anonymous component, which is described as great for trying it out or enabling Blaze on specific templates. The second is optimizing entire directories from your service provider, which is ideal for optimizing many components at once, by calling Blaze::optimize() in your AppServiceProvider. Either way you then clear the compiled views, with the php artisan view:clear command. The README is direct about the recommended order of operations: start with specific directories, because your app may rely on features Blaze does not support, then gradually expand coverage and verify compatibility against the known limitations. The directory form takes multiple in() calls and supports per-folder strategies.

The provider hook is one call, and it takes a path

The directory optimisation API reads as a small fluent builder. You import Blaze, call optimize(), and chain in() with a path, in this case the components directory under the resources path:

php
use Livewire\Blaze\Blaze;

/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Blaze::optimize()->in(resource_path('views/components'));

    // ...

You can point it at several directories in one call, and the README's example uses two, one for buttons and one for modals. Per-folder strategies are configured by passing the strategy arguments alongside the path, so the icons directory can be memoized and the cards directory folded. To exclude a subdirectory you pass compile: false, which stops that tree being compiled while leaving the rest of the parent directory optimised. The precedence rule is worth remembering: component-level @blaze directives override directory-level settings.

The compilation output is a plain function with a data array

The mechanism is visible in the before and after that the README shows. A component template with @blaze and a @props declaration compiles into a PHP function with a hashed name that takes a data array and a slots array, pulls the type out of the data with a null coalesce, and builds a BlazeAttributeBag from the same data. When the component is included, Blaze calls that function directly, and the call site becomes a function invocation with the props as an array and the default slot as a named entry:

php
function _c4f8e2a1($__data, $__slots) {
    $type = $__data['type'] ?? 'button';
    $attributes = new BlazeAttributeBag($__data);
    // ...
}

The bag class is the part that preserves Blade behaviour, because merging attributes is what a plain array cannot do. The function name is derived from the template, so the compiled output is cacheable alongside the compiled views, which is why the view cache has to be cleared when you enable Blaze.

Memoization caches the output, folding removes the component

The two advanced strategies do different things, and the README is careful to separate them. Memoization is caching for repeated renders, aimed at icons, avatars and other elements that appear with the same props, and the output is cached based on the component name and the props passed to it, so a memoized component appearing several times on a page renders only once. There is an important constraint: memoization only works on components without slots, and the rewritten output shows the cache key being computed, the render happening inside a conditional, and the cached result echoed afterwards. Compile-time folding is the more aggressive option, where the component ceases to exist at runtime with no function call and no variable resolution, just the HTML, and the README says rendering time remains constant regardless of the number of components. Both are off by default, and the table lists the parameters with their defaults, compile true, memo false and fold false.

The limitations list is the real decision document

Before you enable this anywhere, read the limitations list against your own templates, because several of these are everyday Laravel features. Class-based components are not supported. The $component variable is not available. View composers, creators and lifecycle events do not fire, so anything that hooks into a component's lifecycle stops happening. Auto-injecting View::share() variables is not supported either, with the workaround given as accessing shared data manually using $__env->shared('key'). Cross boundary @aware between Blade and Blaze does not propagate, and both parent and child must use Blaze for values to pass. And rendering a Blaze component with view() will not work, since Blaze components can only be rendered using the component tag. That last one is a blunt constraint, because view() is how you render a component with a dynamic name.

A MIT package with an upgrading guide and a testbench

The package sits under the MIT licence with a LICENSE file at the root, and the repository layout is what you would expect from a Laravel package: a src/ directory for the implementation, config/ for configuration, resources/ for the shipped views, tests/ and a workbench/ directory, a composer.json, a phpunit.xml, a testbench.yaml and an UPGRADING.md file. The presence of UPGRADING.md is the practical signal about the release line, since the recent tags are all v1.0.x, v1.0.19 on 2026-09-15, v1.0.18 on 2026-08-24 and v1.0.17 on 2026-08-18, with the last push to the repository on 2026-10-11. The homepage is blazephp.dev, and the README adds one operational note worth knowing: if you use Flux UI, installing Blaze is enough with no configuration needed, which tells you the package was designed to work with that component library out of the box.

Editorial conclusion

Blaze suits a Laravel application with a large set of anonymous Blade components and a performance budget that the standard rendering pipeline is eating, and it suits teams that render the same component thousands of times, such as icon and avatar lists. It does not suit a codebase that relies on class-based components, on view composers or lifecycle events, or on View::share() variables, because those features are not supported and the output is not identical to Blade in those cases. Before adopting, read the limitations list against your own templates, start with a single directory rather than the whole view tree as the README recommends, and note that the last push to the repository was on 2026-10-11 with release v1.0.19 dated 2026-09-15.

Frequently asked questions

How do I install Blaze?

Install it via Composer with `composer require livewire/blaze:^1.0`. After enabling it, either through the @blaze directive or with Blaze::optimize() in your service provider, you clear the compiled views with `php artisan view:clear`.

Which Blade features does Blaze not support?

Class-based components are not supported, the $component variable is not available, view composers, creators and lifecycle events do not fire, auto-injecting View::share() variables is not supported, cross boundary @aware between Blade and Blaze does not propagate, and Blaze components cannot be rendered using view(). The README also notes that if you use Flux UI no configuration is needed.

What is the difference between the three Blaze optimization strategies?

The Function Compiler is the default and is used for general work. Runtime Memoization, enabled with memo: true, caches output by component name and props so repeated components render once, and only works on components without slots. Compile-Time Folding, enabled with fold: true, removes the component at runtime entirely, leaving only the HTML.

How do I exclude a subdirectory from Blaze optimization?

Pass compile: false to the in() call for that directory, for example `Blaze::optimize()->in(resource_path('views/components'))->in(resource_path('views/components/legacy'), compile: false)`. Component-level @blaze directives override directory-level settings.

What performance gain does Blaze report for Blade component rendering?

The README reports rendering 25,000 anonymous components in a loop at 500ms with Blade and 13ms with Blaze, and gives a table by scenario with reductions from 91.9 to 97.4 percent. It notes these figures reflect rendering pipeline overhead, so expensive work inside your templates still affects performance.

Official sources

  1. License: MIT
  2. livewire/blaze on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/livewire-blaze.svg)](https://hysenlabs.com/projects/livewire-blaze)

Was this useful?