Livewire 4 shipped on January 14th, 2026 and the community consensus has settled: view-based, single-file components are the future. The official upgrade guide leads with them. The Laravel.com announcement leads with them. Run php artisan make:livewire counter on a fresh v4 install and you get a single ⚡counter.blade.php file with the class, the template, and any local CSS or JavaScript bundled together. That is the default.
We're not on that path. For new Pixelworx builds we default the project back to class-based components, the v3-style architecture where the PHP class and the Blade view are separate files. Livewire 4 supports this fully. The configuration change is one line, and we think most teams will eventually wish they had flipped it.
Here's the case.
Three styles ship with Livewire 4. The default is not the only one.
Worth being precise about what Caleb Porzio actually built, because the framing in most coverage flattens this.
Livewire 4 supports three component styles, configurable in config/livewire.php under make_command.type:
sfc: single-file (view-based) components. The default. One.blade.phpfile with class, template, optional<style>, optional<script>.mfc: multi-file format. A per-component directory withname.php,name.blade.php,name.css,name.js,name.test.php. Co-located but separated by concern.class: the v3 layout. The class lives atapp/Livewire/Foo.php. The view lives atresources/views/livewire/foo.blade.php. Both fully supported.
Class-based components remain first-class in Livewire 4. Caleb says so directly in the upgrade section of his announcement: "the new single-file format is the default for new components, but class-based components remain fully supported."
Three options. The framework is flexible. Picking the right one is an architecture choice, not a religion.
Separation of concerns is the maintainability mechanism
The single-file argument is convenience. You see the markup and the logic in one place. There's less file-hopping.
Convenience is real, and we'll get to where it earns its place. The stronger argument for class-based isn't taste. It's that the class file and the Blade view answer different questions, and forcing them into the same physical file makes every change harder than it needs to be.
The class file answers: what state does this component hold, what events does it accept, what does it broadcast, and how does it validate? It's the contract. It's also the part that has tests written against it.
The Blade view answers: how does the current state get rendered, and what user interactions does it expose? It's the surface. It changes more often, and it changes for different reasons.
When both live in one file, every diff drags both concerns into review. A typo fix in the markup looks indistinguishable from a logic change to anyone scanning git history. The view's churn rate pollutes the class's git blame. Two files give you two cadences, and that distinction is load-bearing for any codebase past month six.
What single-file architectures do to component size over time
We can't honestly claim to have watched Livewire 4 single-file components rot, because Livewire 4 has only been out since January. What we can speak to is the pattern in single-file architectures generally, which is older.
Vue's single-file components have been the dominant style there for years. So has the JSX-everything-in-one-file pattern in React. The trajectory rhymes across every project we've worked in or inherited that used either: a component starts small, picks up a slow accretion of edge-case logic that nobody wants to extract for a "section only used once," and three to six months in it has crossed whatever line your team would normally split at. In a multi-file setup, the discomfort of a growing class file is the signal that triggers a refactor. The single-file format removes that signal because the file is "supposed" to be long.
This is the part we're predicting will play out the same way in Livewire 4. We may be wrong. We're not betting our client codebases on finding out.
What class-based gets you that single-file makes harder
A few specific advantages that aren't about taste:
Testability. PestPHP feature tests target the class. When the class is its own file with a visible public surface, the test reads as a script against an API. With everything bundled into one file, the testable surface is still there but harder to see at a glance.
Targeted edits with coding assistants. When you ask a coding assistant to "fix the validation in the email field component," you can hand it just the class file. The view doesn't need to come along. Smaller context, sharper edit, fewer hallucinations than handing it 300 lines of mixed concerns.
Trait reuse. Class-based Livewire components compose with traits naturally. A pile of components that share form-handling logic gets that logic extracted into a trait without ceremony. Single-file components technically support traits since the new class extends Component form is still a class, but the seam between the bolt-on logic and the inline view becomes visually messy.
Git review. Two files. Two diffs. Two reasons to change. Review tools handle it cleanly. Single-file collapses multiple concerns into one diff and either the reviewer reads carefully or skims and misses something.
Where single-file does earn its place
We're not absolutists. The single-file format is the right call in two specific places:
Small, single-use components with under about 60 lines of total content. Buttons with state. Counters. Toggles. The kind of thing that has no business growing.
Throwaway prototypes meant to validate an idea in an afternoon. Use the convenience. Throw the file away when you graduate.
Everything past that line gets the class-based treatment in our codebases. We default the entire project to that style by setting make_command.type to class in config/livewire.php. After that, php artisan make:livewire foo produces the v3-style two-file pair organized into the same entity-directory structure we use everywhere else.
The real Livewire 4 wins don't depend on single-file
The marquee features of Livewire 4, all confirmed in Caleb's announcement, work fine on class-based components:
- Islands let you mark regions of a component that update independently, with computed-property isolation so refreshing one island only runs that island's queries.
- Scoped CSS and JavaScript ship alongside the component and are served as native cached files.
- Optimistic UI directives (
wire:show,wire:text,wire:bind,$dirty) update the page immediately without a round trip. - Drag-and-drop with
wire:sortis in core, no external library needed. - View transitions through the browser's View Transitions API, configurable per-action with
#[Transition(type: ...)].
None of this is gated behind picking single-file. The framework treats both styles as first-class. The community lean toward single-file is a community lean, not a framework mandate.
What this looks like in practice
For new Pixelworx custom software builds, the Livewire boilerplate sets make_command.type to class. New components arrive as two files, organized by entity directory, following the same conventions we use everywhere else in the codebase. The class file is the contract. The view is the surface. Same way we've built Laravel apps for years, same way we'll build them next year.
If you're inheriting a codebase and the team has gone all-in on single-file, you don't have to rip it up. But the next time you find yourself scrolling past 300 lines to find a validation rule, ask whether the file is doing you any favors.
We've thought about this same question for years across the whole TALL stack. Our position for our own builds and our clients' is the same: keep concerns separated, keep files focused, and let the framework be flexible enough to support both styles even when the loudest voices prefer the convenient one.