VOOZH about

URL: https://blog.logrocket.com/livewire-vs-inertia-js/

⇱ Livewire vs. Inertia.js: Comparing Laravel frontends - LogRocket Blog


2021-09-04
1846
#laravel#vue
James James
24557
👁 Image

See how LogRocket's Galileo AI surfaces the most severe issues for you

No signup required

Check it out

Editor’s note: This article was edited and updated in September 2021 to include a comparison of Livewire with Inertia.js, which is the new way to leverage a Vue.js frontend with a Laravel backend.

👁 Laravel Livewire vs. Vue

Blade is an awesome templating language that allows us to make full-scale, dynamic Laravel app views. However, many modern apps demand page components update without page reloads, and it is cumbersome to do this with traditionally-made Laravel apps that use Blade and JavaScript libraries like jQuery.

On the other hand, single-page applications (SPAs) built with JavaScript frameworks such as React, Svelte, and Vue are known to do this with no hassle.

Thanks to contributors in the Laravel community, there are now a few ways in which we can build these types of applications. In this article, we’ll discuss two of the most popular frontend technologies that are used to build modern web apps with Laravel: Livewire and Vue.

🚀 Sign up for The Replay newsletter

The Replay is a weekly newsletter for dev and engineering leaders.

Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.

Prerequisites

To follow along with this tutorial, you’ll need:

  • Some knowledge of Vue 3 (or at least Vue 2)
  • Knowledge of Laravel
  • Experience using Blade to make templates

Background

Since Laravel 8, there are now two main ways in which authentication and the frontend in Laravel applications are scaffolded: Laravel Jetstream and Laravel Breeze.

With Jetstream, we can scaffold Laravel apps with authentication, email verification, password reset system, session management, frontend with Tailwind CSS, etc. There are also two frontend technologies that we can choose to build these apps with: Inertia.js and Livewire.

Laravel Breeze is somewhat similar, but is a much simpler way to set up an application with auth and frontend scaffolding. The other difference is that Breeze only comes with Inertia.js.

Inertia.js is a JavaScript library that connects a JavaScript frontend to a different backend without the need for an API. Apart from Vue, Inertia.js allows us to connect React and Svelte frontends as well.

So, instead of reaching for heavily complex React frameworks — such as Gatsby and Next.js, and Vue frameworks like Nuxt.js — to handle data-fetching, data-handling, and routing on the server, we can use the magic of Laravel on the backend.

Laravel Livewire promises the SPA experience that comes with React and Vue but without all of their complexity. Livewire components make AJAX calls to the server and though the response is HTML, instead of reloading the whole page with the new HTML, Livewire mutates the DOM with the changes.

Setup

In this article, we’ll be talking about the context of using Jetstream and Breeze. However, you should know that you don’t need to use Jetstream or Breeze in order to use Livewire or Vue.

Vue already comes pre-installed in Laravel, and all you’ll need to do is use Laravel Mix to compile the Vue components into a single JavaScript file that is browser-ready.

For Livewire, all we’ll need to do is run composer require livewire/livewire and include the directives in Blade. However, in this context, we’ll be using the scaffolding provided by starter kits such as Laravel Breeze and Jetstream.

Laravel Livewire

To install Livewire with Jetstream, Jetstream must first be installed into a fresh Laravel installation by running:

composer require laravel/jetstream

Afterwards, run php artisan jetstream:install livewire to install a variety of components associated with Livewire.Then, run php artisan vendor:publish --tag=jetstream-views to publish and use Blade components with Livewire, such as inputs, modals, and buttons.

Frontend assets will still need to be installed by running npm install && npm run dev. The database will also need to be migrated by running php artisan migrate.

Inertia.js

To install Inertia with Jetstream, Jetstream must be installed into a fresh Laravel installation by running:

composer require laravel/jetstream

Inertia can be installed by running php artisan jetstream:install inertia. Combine the frontend assets by running npm install && npm run dev and migrate the database by running php artisan migrate.

To get Inertia installed with Jetstream we must first install Laravel Breeze by running composer require laravel/breeze --dev.

Afterwards, install Breeze’s components by running:

php artisan breeze:install vue

Breeze also gives us the option to use React, but we won’t be talking about that today.

Install and combine the frontend assets by running npm install && npm run dev. The database will also need to be migrated: php artisan migrate.

Creating components and templates

Inertia handles components and templating very differently from Livewire because Inertia is responsible for helping a PHP backend “talk” to a JavaScript frontend, while Livewire extends features that are already available in Laravel.


Over 200k developers use LogRocket to create better digital experiences

👁 Image
Learn more →

For example, let’s consider a simple counter feature where we’ll need to increment by one every time a button is clicked.

With Livewire, we create a Counter component where we initiate our $count property and have a render() method that loads the view.

<?php

use Livewire\Component;

class Counter extends Component
{
 public $count = 0;

 public function render()
 {
 return view('livewire.counter');
 }


 public function increment()
 {
 $this->count++;
 }
}

We then embed Livewire into our view by including this line in our Blade file: @livewire('counter'). With the wire:click directive, we can then bind the click event so that we can run the method on the backend whenever the event is triggered on the frontend.

<div>
 <button wire:click="increment">Count</button>
 <span>{{ $count }}</span>
</div>

The fact that we don’t have to write a line of JavaScript to get interactive components is very attractive to many PHP developers who are not fans of writing frontend code. Livewire developers also have the added luxury of sticking with Blade and having access to all its directives and features.

For Laravel developers that don’t mind delving into JavaScript-land, Inertia makes creating JavaScript SPAs very simple. On the backend, we can send data to the frontend through the controller/route and the use of methods and helper functions. In the example below, we have our CounterController, which has a $counter property that holds our increment value and our increment() method.

<?php

namespace app\Http\Controllers;

use Illuminate\Http\Request;
use Inertia\Inertia;

class CounterController extends Controller
{
 public $counter = 1;

 public function index(){
 return Inertia::render('Home/Index', [
 'counter' => $this->counter,
 ]);
 }

 public function increment(Request $request){
 $count = $this->counter + $request->count;
 return Redirect::route('home', ['counter' => $count]);
 }
}

Before we move forward, let’s put it out there that having a counter app that talks with a backend would be overkill. Vue already has the tools in place to do this on its own. But for demonstration purposes, you’ll see two buttons below: one that increments via Vue alone, and one that increments with the help of Inertia and our backend.

<template>
 <button @click="count++">Via Vue: {{count}}</button><br>
 <button @click="countup">Via Inertia: {{total}}</button>
</template>
<script>
export default {
 data(){
 return {
 count: 0,
 vuecount: 0, 
 total: this.total
 }
 },
 computed: {
 total() {
 this.vuecount = this.vuecount + this.$page.props.counter
 return this.vuecount
 }
 },
 methods: {
 countup() {
 this.$inertia.post('/counter', {count: this.vuecount})
 }
 }
}
</script>

Accessing data

Before Inertia, the only way to share data with a Vue frontend was through a REST API. Now, how data is shared and accessed in the frontend doesn’t have to be a major consideration when choosing between Inertia and Livewire. The only issue is that more lines of code will need to be written on the frontend.

There is a huge difference between the ways Livewire and Inertia render data. All requests for Livewire are rendered on the server side, while all requests for Inertia are rendered on the client side. Both have their advantages and disadvantages.

With client-side-rendered apps, requests are redirected to a single empty HTML file, where JavaScript compiles everything. These apps are usually very fast, but the disadvantage is that SEO sometimes suffers (search engines like Google are still able to crawl JavaScript files).


More great articles from LogRocket:


With server-side-rendered apps, the markup and the data is compiled on the server before it is served to the client. This is the way the web has worked since the beginning, but the problem is that this method is slower.

Even though Livewire and Inertia both have their weaknesses, there are solutions to cover for them. In Livewire’s case, components can be cached after the first render. For Inertia.js, an SSR solution is currently being built where the page will be rendered server-side on the first load, but subsequent requests are done client-side.

Reactivity handling

Reactivity describes the way modern applications are dynamic and change based on user interaction. Livewire and Vue handle reactivity quite differently.

Vue handles reactivity by tracking the changes to specific variables and re-rendering the affected parts of the DOM. When creating Vue components, you define variables for Vue to track (reactive data). Here’s an example with one reactive variable, message.

<template>
 <h2>{{message}}</h2>
</template>
<script>
export default {
 data() {
 return {
 message: "Hello World!"
 }
 }
}
</script>

In the above example, Vue tracks every change made to our example message and will update h2 appropriately. These updates are happening on the client side — it does not need to interact with the backend because the state of this component lives in the browser.

However, there are times when the state in the browser needs to be in sync with data from the database, in which case AJAX will update both the frontend and the backend to be in sync with each other. The problem is, if something happens and an update fails, which causes the frontend and backend to fall out of sync, problems could arise.

By contrast, the state of a Livewire component resides on the server. This, similarly, has its advantages and disadvantages.

<?php
namespace App\Http\Livewire;

use Livewire\Component;

class HelloWorld extends Component
{
 public $message = "Hello World";


 public function render() {
 return <<<'blade'
 <div>
 {{message}}


 </div>
 blade;
 }
}
?>

For simple components like the one above, there is no effect of the state being stored on the server. However, for dynamic components that update frequently based on user interaction, several AJAX requests have to be made to update the state in the server.

This may cause some performance issues. The developers of Livewire propose that to combat this, developers can use “dirty states”.

Conclusion

In this guide we explored the differences between Livewire and Vue and highlighted areas in which they both shine and fail.

To be fair, currently, your choice of framework mostly will come down to whether you like working with JavaScript or not. In most use cases, Livewire provides the same power and dynamism as JavaScript apps.

Vue is already built for reactivity, but Livewire lives on the browser, so SEO won’t be a problem if you want to be on less-advanced search engines than Google. Laravel developers are spoiled for choice.

LogRocket understands everything users do in your Vue apps.

Debugging Vue.js applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Vue mutations and actions for all of your users in production, try LogRocket.

👁 LogRocket Dashboard Free Trial Banner

LogRocket lets you replay user sessions, eliminating guesswork by showing exactly what users experienced. It captures console logs, errors, network requests, and pixel-perfect DOM recordings — compatible with all frameworks.

With Galileo AI, you can instantly identify and explain user struggles with automated monitoring of your entire product experience.

Modernize how you debug your Vue apps — start monitoring for free.

👁 Image
👁 Image
👁 Image

Stop guessing about your digital experience with LogRocket

Get started for free

Recent posts:

Stop hardcoding LLM SDKs: Dynamic LLM routing with OpenRouter and Next.js

Build dynamic LLM routing in Next.js with OpenRouter, TanStack AI, task classification, model fallbacks, and cost-aware routing.

👁 Image
Chizaram Ken
Jun 16, 2026 ⋅ 13 min read

What is TSRX?: What JSX would look like if it were designed today

TSRX adds first-class control flow, conditional hooks, and scoped styles to React via a TypeScript compiler extension — no new framework required.

👁 Image
Ikeh Akinyemi
Jun 12, 2026 ⋅ 6 min read

How to add authentication to a React Native app with Better Auth

Learn how to build a full React Native auth system using Better Auth and Expo — with email/password login, Google OAuth, session persistence, and protected routes.

👁 Image
Chinwike Maduabuchi
Jun 9, 2026 ⋅ 13 min read

AI dev tool power rankings & comparison [June 2026]

Compare the top AI development tools and models of June 2026. View updated rankings, feature breakdowns, and find the best fit for you.

👁 Image
Chizaram Ken
Jun 8, 2026 ⋅ 11 min read
View all posts

Hey there, want to help make our blog better?

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now