Migrating to a Vue SPA and Tailwind

Edvinas Paulauskas
StreetGroup
Published in
5 min readOct 11, 2022

--

Last year, we set out on a journey of updating the design language of Spectre. The product has grown rapidly since its inception way back in 2015 and we thought now was a good time to give it a more modern look and feel. Our wonderful design team started putting designs together and we got to implementing them, but we soon found ourselves having some interesting conversations about our frontend stack.

Integrating a new design system into what we already had was proving challenging. Spectre was built using Bootstrap and had an already established theme. As good as Bootstrap is, we found ourselves having to work around the framework in most cases, adjusting the styling of the existing elements to fit the new design language, trying to keep the old design system in place but also develop a fresh look alongside it.

While trying to make the two design systems work in tandem we also noticed that we were writing a lot of reusable utility classes for spacing, sizing, colours, etc. We really liked the approach as it allowed us to move quickly and build a set of really flexible and reusable building blocks. However, after a while it just felt like we were reinventing what was already out there — Tailwind CSS.

But styling was only one part of the puzzle…

At the time, our platform was using a mix of jQuery, Vue and Blade on the frontend. jQuery was mostly used for older parts of the system, while Vue was used for any newer bits where we needed interactivity, keeping Blade for rendering any non-interactive content on the server.

We really liked working with Vue, so the idea was to go all in on Vue and eventually phase out jQuery, keeping the approach of Vue components for interactivity and Blade for everything else. But the approach was proving itself rather tedious as using Vue components in Blade pages often involved cumbersome setup and muddied the lines between what should be in Vue and what should be in Blade.

On top of that, using a mix of frontend technologies made our frontend a lot more difficult to test. We either had to write multiple test-suites with different technologies or rely on expensive end to end tests to give us more confidence when making frontend changes.

It was clear that our frontend wasn’t great to work with. We couldn’t move as quickly as we’d like and deliver the interactive experiences we wanted to deliver, so we started considering our options.

For styling, Tailwind CSS felt like a no-brainer. It fit well into how we worked and fit our new design language even better.

The JavaScript side was a little more tricky though. We wanted to continue down the path of using Vue, but didn’t want to mix it with anything else to avoid complexity. An SPA felt like a natural direction of travel, but we really didn’t want all the baggage that came with an SPA — particularly developing and maintaining an API and complex state management.

After exploring our options, we landed on Inertia. It fit the bill perfectly. We could have a Vue-only frontend without having to worry about how it had to interact with our backend. We could continue writing our backend the same way we always have, but instead of Blade, we’d now be using Vue.

We had our dream frontend stack of Tailwind CSS, Vue and Inertia, but we still needed to figure out how to migrate to it. We couldn’t just throw away what we already have and completely rewrite the whole system, it’s far too big! We didn’t want to mix Tailwind and Bootstrap either, that felt like taking on tech debt before even writing a line of code using the new tools.

We decided that, ideally, we’d do a clean cut — separate the old and the new completely. In order to achieve that, we had to recreate the main application “shell” (sidebar and top navigation bar) in Vue and Tailwind. It wouldn’t be a 1 for 1 copy, but close enough to not result in a jarring user experience when switching between pages. This completely separated our old Blade/Vue/jQuery/Bootstrap setup and the new Inertia/Vue/Tailwind stack.

As a team, we agreed that anything new is going to be developed using the new frontend stack. As for the old frontend, we’d put it on life support, maintaining it where necessary and porting pages over to the new frontend whenever feasible.

All of this would give us the clean cut separation we wanted and would act as a barrier between the old and the new.

We went forward with the approach.

And it worked out really well! We’re now delivering our first bits of functionality using the new stack. It’s not only allowed us to deliver some of the best and most interactive user experiences in Spectre, but also do it with confidence through unit testing. It has been a really exciting journey and we can’t wait to build more amazing things!

If you like working with Laravel, Vue, Tailwind and Inertia — we’re hiring!

If you have any questions or want to chat, feel free to reach out to me on Twitter or LinkedIn 👋

--

--