Taylor Otwell: “Avoid Separate SPAs consuming Laravel API. Use Livewire/Inertia.”

**Update:** apparently the title of this post was misleading and started a fight on Twitter. Unfortunately, I can't edit the title, but it should have been something like "Laravel Snippet #24: Taylor talks about SPAs vs Livewire/Inertia" to be less provocative. Sorry if this misguided or insulted anyone.

\- - - - - - - -

Last week Taylor released a new podcast episode of Laravel Snippet, explaining Fortify, Jetstream, Breeze and why they were created. I totally recommend listening to [a full 20-minute episode](https://blog.laravel.com/laravel-snippet-24-fortify-jetstream-breeze), but what struck me was his opinion on the architecture of Vue SPA and Laravel API, which grew pretty popular over the last years. So I will just quote exactly, word for word, what Taylor said, and let's discuss in the comments.

>I had just built Laravel Vapor using a Vue SPA as a front-end architecture, and I just don't enjoy using Vue Router, I don't enjoy writing applications in that style, I think using Livewire or Inertia is a much more productive, much faster development experience.
>Inertia, in my opinion, is a much more productive way to use Laravel and Vue together in one monolithic application, compared to using Vue CLI or React CLI that have a separate SPA.
>I still see people wanting to build these separate SPAs that consume Laravel API, to this day. I really don't think it's a good idea, and I think you should avoid it, if at all possible, because it introduces a lot of complexity, not only in your local development but also in your production deployment strategy. Now you have to deploy two repositories at the same time, and you have to think about bundles, breaking changes of your Laravel API. And, honestly, it's just a headache that you shouldn't volunteer yourself for. If you HAVE to do this for some serious architecture thing at your organization, then fine, but you shouldn't take this unwillingly, this should be like a last-ditch thing that you have to accept.
>Otherwise, in my opinion, you should just always use something like Inertia or Livewire, because your life will be much much easier.
>I think a lot of SPA consuming Laravel stuff, if it's not being forced upon you, it's sort of people don't feel cool unless they're building it that way, but, honestly, it's just a nightmare.

What do you think?

If you have built SPAs separately with Laravel API, are you switching to Livewire/Inertia now? Or maybe you have the reasons to disagree with Taylor and keep building it that way?

Personally, I agree with Taylor, it's much quicker to build an app that is just Laravel and then put in Livewire where the actual dynamic modern UX without page refresh is needed, than building the whole architecture on Vue Router, with all complexity included.

39 thoughts on “Taylor Otwell: “Avoid Separate SPAs consuming Laravel API. Use Livewire/Inertia.””

  1. Personally I love inertia. I converted an SPA to inertia and it functions better and is easier to maintain. Not saying I would never SPA again, just that I’ve had a great experience doing about 5 apps with it.

  2. I haven’t used Interia or Livewire, but from my understanding so far, if you are using Laravel as the backend for a SPA, iOS and Android application, then interia/Livewire wouldn’t work as a replacement to a SPA in any sense because iOS and Android apps still need to consume an API. Is this correct?

    That’s primarily why I picked a a complete separation between client (Vue SPA, iOS and Android app) and server side (Laravel API) to begin with – because it makes adding new clients that don’t consume HTML possible

    Seems like the advice from Taylor is really focused on applications which you expect to stay as web apps and never have a mobile application in the future for?

  3. I don’t have anything against Laravel-served frontends, but as someone who actively creates Laravel-backed APIs for separate frontends (Usually Vue/Nuxt, but sometimes things like Electron), the separation of backend and frontend “just makes sense”, especially when deployments are factored in.

    Deployments with separated responsibility aren’t really an issue at all – monorepos are continually rising in popularity, and with companies like GitHub, GitLab and most (if not all) CI/CD providers having a decent level of support for monorepos (E.g. if frontend/ changed, deploy frontend), it’s definitely the way to go if you do want to separate frontend from backend.

    Having flexibility on how my APIs and Frontends are deployed also works to this – sometimes I’ll need a serverless SSR frontend, sometimes statically hosted, and so on, whilst the entire time I’d rather keep my Laravel API hosted on Vapor for obvious reasons.

    Inertia, Livewire and serving frontends via Laravel is great and easy. But it’s not nearly as daunting a task as I think Taylor is making it out to be.

  4. I’ve been using inertia since Jonathan first announced it, and it’s certainly become my go to over blade and live wire. I’ve certainly found that clients expect the front end magic that you get from many online offerings, that you don’t get from just blade – so for me Inertia allows an easy Vue Laravel combo without any of the usual tedium and complexity of complete separation – so I totally get what Taylor is saying and agree to that extent. However, we also have some projects that have multiple front ends and apps to one massive backend “engine” – so neither inertia or live wire would fit nicely – so we’ve gone the api / SPA route – but they’re totally the “have to” edge cases Taylor is talking about.

  5. You have to match your stack with your needs. If all you need is web with reactive components then Livewire/Inertia should be your go-to. If your needs go beyond just web then an SPA/PWA is great. If my project requires desktop, android, ios, etc along with web then I make a PWA in Vue, wrap it in Capacitor (from Ionic), and build for each platform. 2 repos (PWA and Laravel) instead of 4-5!

  6. I thought he should have mentioned that Laravel Sanctum provides first-class support for doing SPA’s via an API if you do have to go that method for some reason. We’re getting to a level of maturity now where you can truly choose whatever suits you best:

    1. PHP only (Breeze)
    2. PHP + a little JS (LiveWire)
    3. Mostly JS, but with PHP routing, controllers, etc (Inertia)
    4. Fully JS, with just PHP on the back-end (Sanctum)

  7. I have several spa with vue and laravel api, I dont regret it. It was a ton of fun building it, but it had a ton of challenges. ( also was easy to ‘convert’ to android / ios apps )

  8. Think Taylor is overstating the difficulty of deployments here. It’s really not a problem especially when using Laravel’s own Vapor and Forge tools.

    I get the issue with Vue router I hated that to. Nuxt is a much better way of a building Vue apps it handles the routing for you.

    I have built an app with an Inertia because I knew there was only ever going to be a single frontend and it was great.

    In my current work I have a core API system and five different Nuxt frontends to consume it. Later down the line a mobile app and POS systems will be talking to it. So I built this from the beginning as separate concerns.

    Point is it depends on what your doing. I didn’t listen to the podcast but if your snippet encapsulates the full discussion I think Taylor needs to perhaps provide more context to prevent listeners taking it as gospel. He is talking about a single web app like Vapor/Forge/Envoyer etc that will only have a single frontend.

  9. I disagree with this opinion. The problem with Taylor statements on the matter is that he does this from the perspective of solo entrepreneur who builds stuff for his own business (or otherwise we’re talking about very small cohesive team with people of similar skills).

    When you hire a React/Vue dev, you don’t want him to spend weeks learning Laravel or that Livewire/Inertia stuff to be productive. Moreover, the deployment of React/Vue SPA these days is as simple as connecting your GitHub repo to Netlify or Google Cloudbuild/App Engine, etc. and just watching CI deploy new changes “auto-magically” to static hosting, so the complexities of deploying separate SPA are vastly overstated. It’s actually considerably simpler that deploying monolithic Laravel app these days.

    These people (referring to certain influencers in Laravel community that speak strongly against SPAs) fail to understand that SPA are all the rage right now not because people think they’re cool, but mainly because they make sense for **their business**. It’s about separating responsibilities in a team more than it is about making twitchy interfaces. Having API + SPA separately improves your hiring process and allows you to have groups of professionals with different expertise focus on their own challenges.

  10. I migrated a big Yii 2 project to Laravel API + SPA. One of our investors actually wanted to do it and sold everyone else on the benefits. I wanted to refactor a lot of the guff that had accumulated whilst we found our ‘product-market-fit” and so allowed it to happen.

    Promise: it’ll make building a mobile app easier in the future.
    Reality: we still don’t have a mobile app.

    Promise: it’ll make the site lightning fast and improve conversation/ page rank.
    Reality: first page load is slower, and that’s what actually matters (SEO and user bounce)

    Promise: separation of front and back end will give us a more robust and reliable product.
    Reality: no it won’t. It’s harder to debug and so it has more bugs.

    I think a lot of my other issues with it are on the SPA side. I actually really like Laravel for APIs and have some lovely patterns that serve me really well.

    I think the reality for me is that I’m just not sold on SPAs anymore.

  11. Inertia is the best. Easy to setup and use. Everything’s integrated in Laravel.

    Laravel Nova is such a pain in the ass to customize. You need to use vue-router, apis and so.

  12. This is a case by case scenario. I feel blanket statements like these hurt more than they help. If the requirements involve separate frontends on static hosts then SPA makes sense, but if this is not a requirement then Inertia serving laravel frontend makes sense, or livewire.

  13. TBF I had one inherent difficulty with SPA : handling permissions when you have a complex permissions system. But it was the only one I think.

    The rest is just better IMO : instant load time for static content, one time subscription for WS, basically having an app-like behaviour much more easily than with native stacks.

    And no you don’t have to use a separate repository.

  14. I don’t think I’ve ever met anyone that enjoys working with Vue router. It is just a lot of work and pretty messy. Nuxt has an “auto routing” feature, and makes vue development much more enjoyable. I probably wouldn’t have started using Vue at all without the recommendation from the Laravel community, but I am glad I did. I do not plan on using Livewire or Inertia any time soon, both look like good project but they do not appeal to me at the moment.

  15. I think people here are overstating who he might be addressing.

    There is no denying things get more complex as you add more stuff and separate concerns further. I’ll add a few more things that aren’t really hard to do

    1. Vanilla Laravel
    2. Livewire/Inertia
    3. SPA
    4. DDD
    5. Microservices

    If you have been around long enough you know the more complexity you add to something the more “tax” you have to pay to maintain that complexity. More things to upgrade, more things to deploy, more things that can break in new ways, more things to train and on board people. You 100% get more flexibility but it is by no means free.

    A lot of younger developers go straight to a spa or microservice level because as Taylor puts it “people don’t feel cool unless they’re building it that way”. They read posts on how Netflix or Facebook or whoever is building out their huge apps and think their basic CRUD app needs all of those bells and whistles when they don’t even have multiple developers working on different services let alone large teams working on them.

    We’ve been down that path, and in some cases have swapped out php to rust in a api cluster to save on server costs, which only a microservice would let us do, but that is by no means as cheap to develop as a vanilla laravel app.

    So while he may be overstating how hard somethings things are (like deploying a front end separately) I think it is still sound advice. The large majority of the web can be solved with #1, obviously if you are required to develop ios/android apps you will save time overall with #3

    I think his goal is to get people to sit down and think: “what do I really need here?” rather than “what is the most technically sound solution I can come up with to account for all possible future needs?”

    Or another way to think about things: whats the most profitable route for me to get my app up and making money. Young me wanted “to be the best” old me “whats the minimum I need to be successful”.

  16. As always, thanks for posting Povilas!

    This might sound arrogant, but it feels that Taylor has very limited experience in actual projects. Everything he does seems suited for a particular kind of apps (SAAS) and all the suggestions are tailored to that. But in actual jobs most projects are different. Websites, APIs, SPAs, CRMs, eCommerce and so on, but very rarely it’s a SAAS.

    I’ve worked on something like fifty Laravel projects and I’ve still only had one project where users are allowed to register themselves… which comes by default in Laravel and had to be manually removed until last year. And every project needs a page where an admin can manage users. And none of the Laravel scaffoldings include that.

  17. Some have already pointed that out, but this Inertia/Livewire approach is not really suitable for getting separate frontend and backend developers/teams. Having unified backend team that defines an API for all the public apps is a huge perk.

    I personally liked Vue Router. Laravel’s router is simpler and better, but not at the cost of Inertia’s overhead. I disliked Vue CLI, that seemed a
    huge overhead of nothing… I’d rather play with Vue alone.

    But, if you have the project where you can afford to mangle frontend and backend together, do you even need Intertia? What I do on those projects is do Laravel routing and have a really simple view for each of my pages that places the component. And with ziggy I get Laravel’s routing in JS.

  18. Let’s say I’m sold and I want to switch. Which is it? Inertia or live wire? Why can’t we decide once and for all which one will be the officially recommended so we can invest in learning it. Also just realized that I probably can’t convert my Vue SPA because it’s heavy on keyboard shortcuts, which if I’m not mistaken is not supported by LW or IN

  19. It is just opinion though. He just doesn’t seem to like how other systems did things so he build his own. That’s how a lot of good things started. But I don’t like how he is saying everyone should use it.

    Also his concerns aren’t that hard of a problem all together. And the pro’s outweigh the cons in a lot of cases.

    I hope Taylor doesn’t underestimate how many people use Laravel just for API.

  20. I think he makes very clear he talks about his own experience in his own products. If I listens his podcast, I know I hear his opinions. I dont undrstand why somebody see that as problem or its somehow only preferred way work with Laravel. I personally have both SPA+Laravel API and Inertia/Laravel app and both are solid in their own use cases.

  21. I completely agree. The number of times I’ve seen someone say, “I’m building a SPA with an API”, you ask them why, and they can’t get a reason other than, “I read somewhere it was a good idea”.

    Developers *really* need to make decisions on their own two feet as to whether an architecture style or pattern is actually going to have a tangible benefit, or whether they’re just making decisions because it’s the “hip” thing. Same thing with micro services. “My codebase was getting too big, so I’ve decided to split it into *more* codebases…”

  22. That all makes sense from a small team point of view. But some people work in big teams and complex apps…and in that context I think Taylor’s advice is a bad one.

  23. I have recently created a project by using laravel as an API and NUXT. I think that at the end of the day it just depends on what you need to actually accomplish your (client) business goals. I think is better to use inertia if you don’t require any server side rendering since it not compatible so far. But while developing the API for my NUXT application I found it quite a hustle to deal with 2 different repos, different deployment strategies and also all the testing for front end and backend. ONLY because I needed the server side and I like the user experience that JS frameworks provide.

    I think Taylor refers more to the people like me that are not so experience working with all this tools. I see some nonsense by saying that people choose some things because are cool or not instead of focusing on real world cases but I keep my hand on Taylor side since I encountered what he mentioned about the complexities of having 2 repo. Call it inexperience, but I think this is happening to most of the solo/small team developers

  24. I think both are valid ways to build web applications.

    I’ve built large applications using the old Vue scaffolding that used to be default with Blade, InertiaJS and I’ve used Laravel to build API’s consumed by a React or Vue SPA.

    All have had pros and cons.

    ## Deployments

    I don’t agree with the notion that Taylor is overstating the complexity of deploying an SPA. Yes it’s super easy to spin up a new Netflify site from a git repo and poof, you’ve got a massive portion of your CD done for you.

    But deploying changes to your SPA is never that simple is it? You still have to version your API and you need a way to deploy both the SPA and the API separately without breaking. You can’t just have your SPA changes go out expecting to use updates in the API that haven’t been deployed yet. Solvable yeah. Trivial? Depends on your skill set I guess, but there’s no out-of-the-box solution for this.

    So yeah, a MPA (multi-page app) app built on Inertia or Livewire is going to be easier to deploy.

    ## Complexity of layers

    Separating the two ends of your application into distinct layers (client & server) is beneficial for all sorts of reasons. Supporting multiple clients, especially desktop and mobile clients is one of the biggest benefits. But hiring can also be easier too. It’s easier to hire a frontend developer who’s awesome at Vue or React than one that is awesome at those frameworks AND knows Laravel well too. And if you’re betting your stack on livewire your options are even more limited.

    That said, this client server separation comes with a lot of complexity too. Yes tooling in the SPA ecosystem has come a loooong way in the last few years to alleviate a lot of the complexity but it’s still there.

    1. Authentication/session management is more complicated especially if you don’t opt for stateful sessions.
    2. Data transfer and hydration is more complicated
    3. You’re going to quickly realize you need to version your API
    4. Feature toggles are more complicated to implement
    5. end-to-end testing is now more involved, especially if you want your e2e tests to actually hit a database while still being able to run in parallel. So much so, that there are arguments against doing this in the first place in a client/server separated app
    6. Caching and state management. Arguably this is actually a benefit of an SPA but it is a whole new layer of complexity that lives in your frontend codebase that didn’t exist in your MPA

    Keep in mind, “complex” here doesn’t mean “not possible” or necessarily “more difficult” it just means that it’s more involved, has more layers, possibly more 3rd party dependencies to help abstract the underlying work involved and in general more things for developers to “know”.

    Lots of apps benefit so much from the architecture that the increase in complexity is worth it!

    But I have a really hard time listening to people make the argument that it’s “not that complicated”. You can get a lot of the UX an SPA can offer from an Inertia app and avoid having to figure out all the SPA stuff.

    ## Testing

    Overall I actually enjoy testing so much more when the two ends of my app are seperated. Testing the frontend just feels like there is less friction. When you’re working inside an Inertia or Blade app the tooling in the JS ecosystem always feels like it just doesn’t work without some serious finagling.

    The caveat is that now your e2e tests are a lot harder. You can’t just drop in Cypress, and Dusk isn’t a fan of SPA’s either. Ideally you want e2e tests to run in parallel because they are so damn slow. If those tests are truly e2e you want them talking to a database and the only way to keep tests like that parallel is to have multiple database instances running transactions that are rolled back between tests.

    I haven’t found a solution I’m in love with for that so I’ve just decided to let the API be a hard boundary. With a few exceptions my “e2e” tests are divided between testing the API layer only or mocking the API and testing the front-end only.

    ## Ecosystem

    Laravel is an MVC framework for building multi-page applications. It can be used to create JSON API’s but not very well out of the box. I haven’t found PHP as a language to be particularly awesome for creating Rest or GraphQL API’s actually. Maybe this will change as PHP 8 matures.

    PHP devs often aren’t even aware that in other ecosystems you don’t have to write your swagger docs by hand. 90% of the specification can be inferred when you work in a strongly typed language.

    I find many PHP devs don’t even use Swagger or Open API or know much about it or know much about JSON API specification or any other tools/specs related to API’s at all actually. It just means, Laravel or no Laravel, building API’s in PHP is a bit of an uneven trek through lightly walked trails.

    The tooling in general is just lagging behind other ecosystems like Dotnet, Node/TS and Java. And no disrespect to the contributors working on those projects! There just aren’t a lot of you out there.

    So from an ecosystem standpoint, if you’re using Laravel, it makes a lot of sense to not go the SPA route.

    ## Closing thoughts

    I personally tend to enjoy working in an SPA more, but I also enjoy writing JavaScript a lot more than most PHP devs.

    In the end either approach has trade offs. SPA’s are generally more complicated than people like to admit, but they’re often worth the added complexity except for when they are not.

    Happy building!

  25. SPA is not the problem, we’re in the right track. We just need someone to develop a builder for spa’s app, into a laravel intertia format.

  26. I’m building a Vue SPA with a Laravel back-end right now, and I think Taylor is being far too general in his comments. From what I’ve learned of Livewire/Inertia, it sounds like a great tool for some things. I don’t think there’s anything quite like a SPA though for full web applications like I’m building. They just feel better on the front-end, so I would never do any form of server rendered pages for a web app.

    Also, some of his complaints are silly imo. First off, your front-end and back-end don’t have to be in separate repositories. You can use Laravel Mix to quickly scaffold a Vue app within your laravel repository without needing vue-cli. That’s my preference at the moment. Also, vue’router isn’t that bad either; he’s being dramatic.

    I’m glad that he has found a workshop that he enjoys, but personally I think it’s foolish to believe it will work for everyone.

  27. Every project is unique to whosoever is building it.

    As others have mentioned above: working alone, on your personal projects and businesses is completely different from working with teams.

    I use Inertiajs because I’m familiar with Vuejs, and had a terrible experience working with vue-router (also because its creator Jonathan, has a humble soul),

    Livewire, no comments. I haven’t had an interest in it since its release. Maybe I’m missing out, or maybe I’m just biased by my love of VueJS

    That said, I will choose an SPA with an API backend any day over what he is proposing.

    Again, its just me

  28. >Now you have to deploy two repositories at the same time, and you have to think about bundles, breaking changes of your Laravel API

    This doesn’t make sense to me.

    I don’t feel like deploying 2 repos at the same time should be a headache. It does mean that Envoyer won’t work as easily out of the box. I think Forge would still be fine and easy. I haven’t use Vapor, so can’t say. This is why I think I’d rather opt for deploying with something like Ansible.

    Actually being able to deploy the back-end separately without having to build the front-end would be kinda nice. It would be a lot quicker. Only deploy the front-end when you’ve actually made changes to it.

    And you need to make sure your API doesn’t include breaking changes regardless. Unless you always update the front-end with it as well. Which you could do with an SPA as well, if you really felt the need.

    On a separate note, I think Envoyer and Forge’s UI would be a lot better as proper SPAs. I don’t like the fact that clicking on tabs don’t change the URL. I.e. after clicking on a tab, I can’t use the browser back button to go back. It takes me to the previous page. Which is confusing and frustrating.

  29. We use lighthouse php which enables Laravel to function as a GraphQL backend. GraphQL is life changing for both front and back end- developers. No more discussions about whether we should or shouldn’t go for an API style application.

  30. What???

    Not that building a monolith can’t work – but frankly that opinion is absurd. It makes me question is front end skills.

    There are a ton of reasons to separate your api and front end. This sounds like a backend dev going “eh I don’t want to learn so I’m just doing it my way”

  31. I don’t get all the hate, you should read up and use what you want/need for your use case, I still use the ui package for the auth scaffolding as it’s pretty flexible. It’s great that there are alternatives to use, but in the end it doesn’t matter what Taylor or the other Ruby guy says, just pick what you are comfortable with. You don’t like Livewire (i don’t like it either, reminds me of java ee days), that’s fine nobody is forcing you to use it.

  32. I still prefer things as vanilla as possible, so lumen api + vue, vuex and vue router goes waaay better, is more stable (as it is tested more than live wire or inertia) and scalable. Just in case you have to take part of your frontend code to do something else, saying a PWA (which can be offline)

  33. This just confirms my theories that livewire/jetstream was developed because vue-router and vuex were ‘too hard’. Frankly this whole ‘build it faster’ mentality falls right into suits and executives that demand delivery before something is ready. I’d rather write quality code at the pace I’m comfortable with than write it quickly to make people happy then have to rewrite it all over again for whatever reason.
    To OP’s question, we did switch to inertial with a large/massive Saas and have been rewriting it for months, it’s been time consuming and painful. I see no real value add in the whole jetstream/inertia world. It doesn’t eliminate anything, and realistically it doesn’t make things easier, or harder. It doesn’t eliminate or remove any duplication or redundancy, it just relocates it back into laravel, trying to keep laravel relevant when there are so many other options.
    As for Taylor’s comments on split repo’s, if I have separate teams of UI and API, then the UI team can push code and UI changes live without waiting for unrelated backend developments and vice versa. This in turn makes marketing weasels happy that their updates are live and visible. Functionality updates usually do require deploys in lockstep but there are ways to deal with or resolve that long before it’s even an issue.

    As others here have said, do what works for you and be happy.

  34. Ok, the author of the post here. Unfortunately, this Reddit post started a huge fight yesterday on Twitter, and unfortunately. I can’t edit the post title anymore, which caused people to think I have bad intentions.

    I’m sorry to anyone who got insulted, including Taylor himself.

    I was trying to be a journalist here, posting “from the field” and quoting things exactly as they were. But apparently, I’m not good at choosing words that wouldn’t “start a fire”.

    So from now, I will stop posting posts like this one quoting Taylor or starting a discussion about WHY certain things in Laravel work in a certain way. Instead, I will focus on the educational part of HOW Laravel works.


Leave a Comment