Skip to main content

Laravel Livewire 4 Beta: New Features and Improvements

·1118 words·6 mins·

Livewire is one of the best tools for building dynamic interfaces in Laravel applications without leaving the comfort of PHP and Blade. It provides a seamless way to create reactive components that update in real-time without the need for complex JavaScript frameworks. Livewire 3 is the current current stable version. It came with many improvements over Livewire 2, like wire:navigate, @persist, lazy loading, and more.

Livewire 4 was first revealed at Laracon US 2025, by the creator of Livewire, the legend himself, Caleb Porzio. Recently, in the wire:live event, Caleb announced more details about Livewire 4 Beta, which is now available for testing.

If you visit the Livewire 4 documentation now, on top of the page you will see a banner indicating that Livewire 4 is in beta. This means that while you can start using it in your projects, it’s still under development and may have some bugs, incomplete features, or breaking changes before the final release.

New Features in Livewire 4
#

New Ways to Generate Components
#

In Livewire 3, there were two ways to create components. First is make Livewire class components or functional(single file) components using Livewire Volt. In Livewire 4, the first method mentioned in the docs is like below:

php artisan make:livewire post.create

If you don’t any other flag to this command, it will generate a Livewire single file component. The new component will be created in the resources/views/components/post/⚡️create.blade.php directory with a ⚡️ prefix. This emoji indicates that it’s a Livewire component. The community is arguing whether this is a good idea or not, Caleb mentioned that this is to make it easier to identify Livewire components in your project. The generated component will look like this:

<?php
 
use Livewire\Component;
 
new class extends Component 
{
 
};
?>
 
<div>
    
</div>

Looks like this method will eventually replace Laravel Volt in the future. Another way to create Livewire components is by using the --mfc flag, which stands for “multi file component”.

php artisan make:livewire post.create --mfc

This command will generate a directory named create inside resources/views/components/post/ containing two files: create.php and create.blade.php. They are co-located for better organization. The create.php file will contain the Livewire component class, The create.blade.php file will contain the Blade template for the component. The whole idea is to keep the Livewire components in the resources/views/components directory, not in the app/Livewire directory as in previous versions. But if you want to keep the old class based structure, you can still do that by specifying the --class flag when creating a component.

php artisan make:livewire CreatePost --class

This command will create the Livewire component class CreatePost in the app/Livewire directory and the Blade template in the resources/views/livewire directory, just like in Livewire 3.

This new way of organizing Livewire components is the main change in Livewire 4. You need to either adapt to the new structure or keep using the old class-based structure with the --class flag.

You can also use the php artisan livewire:convert command to convert between different component structures.

Deferred Rendering
#

Imagine you have a web page with quite a few Livewire components. Some components may take longer to load due to complex logic or data fetching. In Livewire 3, all components are rendered immediately when the page loads, which can lead to slower initial load times and a less responsive user experience. Now with Livewire 4, you can put them into the background separately defining the component to be reloaded without the full page reload.

Apply the #[Defer] attribute to any component that should be deferred:

<?php // resources/views/components/⚡revenue.blade.php
 
use Livewire\Attributes\Defer;
use Livewire\Component;
use App\Models\Transaction;
 
new #[Defer] class extends Component { 
    public $amount;
 
    public function mount()
    {
        // Slow database query...
        $this->amount = Transaction::monthToDate()->sum('amount');
    }
};
?>
 
<div>
    Revenue this month: {{ $amount }}
</div>

When the page loads, the deferred component will be rendered as an empty <div></div> and will be rendered in the background. Once the component is ready, it will replace the loading state with the actual content.

You can define a placeholder() method in your component to customize the loading state:

public function placeholder() 
{
    return <<<'HTML'
    <div>
        <svg><!-- Loading spinner... --></svg>
    </div>
    HTML;
} 

Islands
#

Islands allow you to create isolated regions within a Livewire component that update independently. This means that when an action occurs within an island, only that island will be re-rendered, not the entire component. This gives developers the benefits of breakdown of components into smaller parts without the overhead of managing multiple child components.

To create an island, you can use the @island directive in your Blade template:

<div>
    @island
        <div>
            Revenue: {{ $this->revenue }}
 
            <button type="button" wire:click="$refresh">Refresh</button>
        </div>
    @endisland
 
    <div>
        <!-- Other content... -->
    </div>
</div>

In above example, if you click the “Refresh” button, only the island containing the revenue information will be re-rendered, not the entire component. You can customize the loading state of the island by using @placeholder directive:

@island(lazy: true)
    @placeholder
        <!-- Loading indicator -->
        <div class="animate-pulse">
            <div class="h-32 bg-gray-200 rounded"></div>
        </div>
    @endplaceholder
 
    <div>
        Revenue: {{ $this->revenue }}
 
        <button type="button" wire:click="$refresh">Refresh</button>
    </div>
@endisland

Upgrading from Livewire 3 to Livewire 4
#

If you upgrading to Livewire 4, you should run php artisan livewire:publish --config to publish the config file. Then, in the config/livewire.php file, you need to do these changes:

'component_namespaces' => [
    'layouts' => resource_path('views/components/layouts'),
    'pages' => resource_path('views/pages'),
],

'component_layout' => 'layouts::app',

This configuration should be set if you are using Livewire full page components with layouts. In Livewire 4, the layouts become more important, so Caleb recommends and the preferred way is to use full page Livewire components.

Livewire Blaze
#

Caleb has introduced a new package called Livewire Blaze. This may change how Laravel Blade is rendered in general. On this blog post, Caleb explains that Blaze compiler renders Blade components 20 times faster than the default Blade compiler. Basically, if you have lot of Blade components in the same page, which is common in Livewire applications, then Blaze compiler would work with Blade to be much more efficient.

Some prominent Laravel community members predict that Blaze may eventually replace the default Blade compiler in the future, because this how Blade should work by default. Blaze is still in its very early stages, so it’s not recommended to use it in production yet. It’s a exciting project, so you can star the Blaze repository to keep track of its progress.

Livewire 4 Release Date
#

There is no official release date for Livewire 4 yet. We can expect it to be released in the coming months after the beta testing phase is complete. We will update this article when there is an official announcement regarding the release date or any other major updates about Livewire 4.