Why we chose Laravel Spark, and later dropped it

Laravel Spark is a wonderful library to start building your product. I first heard about it a couple of years ago. Being already thoroughly acquainted with Laravel PHP, I found Spark to bring all the missing pieces in: user management (including teams, two-factor authentication, API, announcements, invoicing, billing and payments) and even a Kiosk backend interface where you could see the list of users, impersonate them, watch product metrics and many more. All this for $99. No matter how affordable your development team is, you just cannot build any of that in $99 worth of effort.

I also enjoyed that it had VueJS integrated and for about a year, it made all the difference in getting the business logic in without worrying about the boilerplate.

I recommend getting Laravel Spark to anyone who is building a product, and even more so if it’s a subscription-based service such as a SaaS. For me, it totally made sense to go with Spark, since the 7+ years of experience in running Monitive made me aware of all it had to do beyond user signup and billing. And that’s just what I wanted to do. Focus on bringing value to the user, not on how people log in.

Fast forward a year and a few months, I realized that even though the application was almost ready for customers to use it, it became quite complicated. Not for the user, but for the developer.

As any modern web application should be these days, the new Monitive codenamed “Freyja” was Laravel PHP + Spark + VueJS + Bootstrap. What this meant is that a PHP backend developer needed to do npm install and figure out what was wrong when NPM failed to properly build the application. On the other side of wall, a frontend Javascript developer had to do composer install and configure .env in order for him or her to see his development work in action. This made professional life quite challenging for both. Meanwhile, I was the one stuck in the middle, having to know how both sides work and what to do to fix them whenever an issue popped up.

Long story short, the brand new application became one big monolithic structure that was pretty complicated to extend or deploy.

Even the production deployment document was a thousand lines long with step by step instructions on how to set everything up. So, even though the user-facing part was simple, fast and clean, developing it was quickly becoming a nightmare.

The Split

So, the obvious thing to do next was… to split it: backend PHP (still Laravel) and frontend VueJS. However, this would mean that all the Spark magic would go away, since most of the features it brought were tightly coupled between frontend and backend. I was teasing with the idea of removing everything frontend-related into a brand new VueJS application, leaving all the API and backend stuff in the Laravel Spark PHP codebase that we already built. Quickly during this brainstorming session, Marius, one of the developers, came up with a suggestion: why not switch to Lumen for the backend PHP and use VueJS strictly for the Frontend?

This meant of course, migrating all the code that was already working into a new Lumen deployment, and all the VueJS components into a new VueJS deployment.

It immediately felt like this was going to blow up our roadmap and plans for an early release, but it also felt like the right thing to do.

So, we went for it. Thanks to the unit tests that we already had, migrating all the backend code took less than 20 hours of work. This included integrating Laravel Passport and other goodies that we needed in the Lumen app. As for the frontend migration, this is still ongoing as we’ve also decided to bring design into the equation and start with a mobile-first design approach.

I have to admit, I always liked the idea of building a product or service with a mobile-first approach, because these small-screen, low bandwidth devices are forcing us to focus on the most important things to display and to minimize loading times as much as possible. It makes us strip our idea down to the very core. The desktop version that comes later just means arranging the layout and figuring out what else is useful.

The API is the single source of truth

What I love about separating the frontend and the backend is that the core of the application — the one that actually manages users, monitors downtime, sends outage alerts and generates reports — has no interface. It’s completely separated from what the user sees. This brings many advantages including the fact that the web app, mobile application, 3rd party integrations and everything that you can possible build on it uses the same code base.

Second, the API enforces security, manages access rights and privacy, so there’s no need to worry about nasty private data spilling bugs that a combined application usually has. There’s a low chance of XSS and other vulnerabilities as the API doesn’t even know what cookies are. That’s all browser stuff that the core should never have to worry about.

Third, you can have teams working on the frontend and backend, completely separated. One does not need to know what the other is doing.

And this brings me to my last point, the API documentation. Since the teams are usually separated, the API team has to maintain a really good documentation for the API so that other teams, including users that want to use our API, can easily learn how to use it for their own needs.

Even though we used Laravel Spark for our new product and later removed it, if I were to go back in time, I would do it exactly the same way. In retrospect, it did its part wonderfully: it allowed us to start building business logic from day one, to enable us to see everything in action and to get the real idea on what the end product would look like. Therefore, even though we changed course later on, we kept the concept, the knowledge and the experience.

It was all a worthwhile lesson in the end.