Single File Components in Laravel: The fastest way to program today

Video thumbnail

I'm starting to really like Single File Components (SFC) and I want to explain my reasons. If you've been living under a rock, I'm referring to the Livewire functionality in Laravel where the logic (PHP) and the view (Blade/HTML) reside in a single file:

Aplicaciones web y herramientas online

resources\views\pages\dashboard\category\list.blade.php

<?php
new #[Title('Categories')] 
class extends Component {
    

    function with(): array
    {
        return [
            'categories' => 
            $this->getPaginatedResults(),
        ];
    }
}
?>

<div class="space-y-6">
    <flux:card>
        
    </flux:card>  
</div>

At first, I wasn't convinced. In fact, a year ago I published that I didn't like the Volt approach (whose main feature is precisely the single file). However, I have changed my mind due to how the ecosystem is evolving and the efficiency it brings to the workflow.

Migrating from Scratch: The Opportunity to Clean Up Code

Currently, I am migrating my platform, Desarrollo Libre, from Laravel 12 to Laravel 13. Although functionally it is the same application, doing a migration from scratch allows me to correct organizational errors that I had been carrying for years.

When you are a solo developer and your application grows, it's easy to end up with a mess of poorly named files or disorganized folders. Migrating little by little, starting with the heaviest parts (like the Dashboard), has allowed me to appreciate the advantages of SFCs.

1. Organization and Scroll Efficiency

In the old scheme, I had the main class in one place and the view in another. If I wanted to find a file to save data, I would type "Save" and a huge list of files named the same would appear: save.php and save.blade.php spread across dozens of folders. It was a hassle.

With Single File Components, everything is at hand:

  • Fewer open files: You don't have to jump between the app/Livewire folder and resources/views/livewire.
  • Less navigation: I've halved the path I have to take in the file explorer compared to non-single-file components where I have to look for the class on one side and the view on the other with VERY different locations:
    • app\Livewire\Dashboard\Books\BookSave.php
    • resources\views\livewire\dashboard\book\save.blade.php
  • Modularization: It is much simpler to create clean, reusable components.

2. Cleaner Routing

In modern Livewire, full-page component routing is much more direct. Before, we depended on constant class imports. Now, we can define the route like this:

Route::livewire('/uri', 'component-name');

Being a text-based reference, if you rename a file or change its location, updating the route is extremely simple. Everything becomes more readable and less prone to namespace errors or failed imports, which happens in the traditional scheme when having to change the use and namespace

The Debate: Update or Start from Scratch?

Laravel offers tools like Laravel Boost to automate updates, but I still prefer manual migration for large projects for several reasons:

Aplicaciones web y herramientas online

  1. Elimination of "Zombie Packages": A project updated since Laravel 6 can drag along old packages like laravel/ui, coexisting with Breeze or Jetstream. It's a Frankenstein. By starting from scratch, you only install what you really need (like Flux or the most modern versions of Fortify).
  2. Database Migrations: I take the opportunity to clean up my migrations. Instead of having 50 add_column_to_table_x files, I prefer to consolidate the table structure into a single file, generate the SQL, and run it. By migrating from scratch, you verify that your migrations are well-structured and don't reference columns that don't exist yet.
  3. Modern Configurations: Laravel 13 includes improvements by default (like automatically injected Livewire scripts) that are sometimes lost or become a mess to configure manually in an old project.

Not Everything is Perfect: The Cons

Despite the advantages, there is something that still frustrates me about SFCs: editor assistance (IntelliSense).

I've noticed that in VS Code, a lot of autocomplete and error detection power is lost. Sometimes I'm missing a semicolon and the editor doesn't "shout" at me, or auto-imports fail because the editor gets confused between the Blade block and the PHP block. It's something that will surely improve over time, but currently, it's a point against for those of us who rely heavily on visual IDE help.

Conclusion

If you are working in an ecosystem that changes as fast as Laravel, Livewire, or Inertia, my advice is: every 2 or 3 years, consider rebuilding your base project from scratch. It gives you total control, you eliminate technical debt, and it forces you to learn the new conventions of the framework.

If you want to learn more about how to manage these changes, remember that I have my updated courses and books on the Laravel ecosystem, where I record everything from scratch so you don't get lost in old versions.

I leave you the previous article:

I DON'T like Laravel Livewire Volt

Video thumbnail

I quickly wanted to share my opinion on Laravel Livewire Volt, this technology that Laravel offers us. It's not mandatory yet; at least, it suggests it when creating a Livewire project, asking if you want to use it or not. Once chosen, it installs it and uses it from there on.

Aplicaciones web y herramientas online

Basically, Volt allows you to create both the logic and the visual part—the interface—in a single Blade file. It functions like a component in Vue, where the logic and the view coexist in the same file.

use function Livewire\Volt\{state};
 
state(['count' => 0]);
 
$increment = fn () => $this->count++;
 
?>
 
<div>
    <h1>{{ $count }}</h1>
    <button wire:click="increment">+</button>
</div>

My Opinions on Volt

  • Hinders readability: By having denser files that combine the Blade and the control layer, the code becomes more complicated to read, especially in large projects.
  • Hinders maintenance: You can have traditional Livewire components or ones using Volt, which creates the same problem as anonymous components in Laravel: bifurcations within the project without a clear reason.
  • Unnecessary bifurcation: The same component can exist in your project with two files: the Blade and its separate class, or everything in a single file. This might depend on the number of lines, but it's subjective: how many lines are too many? How many are few? The logic might be small, but the view can be extensive, and that can cause confusion about whether you should split the file or not.
  • Inconsistency in the component pattern: Personally, I prefer that all components follow the same pattern, instead of having some in a single file and others split up. This is a matter of taste, but I believe it adds more clarity and consistency to the project.
  • Issues with anonymous components: Anonymous components are Blade files that have no additional logic. They are useful for simple elements, like buttons, but it is sometimes confusing to identify whether a component has a class behind it or is totally anonymous. This creates a degree of uncertainty when reading or maintaining the code.

Conclusion

I'm not saying that Laravel Livewire Volt is a bad technology or that it should be avoided, but I believe it can generate confusion and maintenance difficulties in some projects. I simply wanted to share my opinion and the reasons why I personally don't usually use Volt in all my developments.

I DON'T like Laravel Livewire VoltI give my reasons why I don't consider Laravel Livewire Volt to be a good tool for developing components.


Únete a la comunidad de desarrolladores que han decidido dejar de picar código y empezar a construir productos reales. Recibe mis mejores trucos de arquitectura cada semana:

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español