I’ve been using Vue a lot recently on a few test projects, and most notably on Buttondown.

Buttondown’s frontend is 100% Vue: around twenty screens (which are themselves components) and around thirty miscellaneous components, tied together with Vuex and Vue-Router.

Overall, Vue is a really great tool, and the first word I’d use to describe it is pragmatic. Almost everything feels and acts sensible; there are tremendously few times that I am confused or surprised by how it works, which is legitimately novel (and wonderous) after the hours and days and weeks I’ve spent pulling my hair out dealing with random React and Webpack arcana.

Still, there are some bugaboos that I think arise from Vue’s current niche as a “lightweight” approach to creating a functional SPA, in much the same way that Flask carved out a niche as being a lightweight alternative to Django.

Testing Vuex-coupled components

Note Vuex is the most popular (and arguably most Vue-blessed) state library for Vue; it's an implementation of the Flux architecture, so it has the same philosophy as Redux.

Testing Vue components sucks.

It’s doable — I’ve done it — but it sucks.

Testing Vue components that rely on Vuex, through things like mapState, is a hellscape.

There’s very little documentation and very few StackOverflow questions to mine. I legitimately cannot figure out how to do this in a non-insane manner.

The sad truth about my approach to testing is that if the ROI isn’t there then I punt on it until it is, which means I have lot of tiny tests for utility methods but no comprehensive front-end testing. And, unfortunately, Vue’s desire lines point you towards encapsulating as much state logic in components as you can, which mean testing suffers.

(One thing I could probably do, but don’t want to because it feels like an anti-pattern, is migrating my usage of Vuex into Wrapper style components, where, say, ScheduledEmailWrapper.vue is a component that takes in Vuex state as computed properties and passes them into ScheduledEmail.vue as props, making ScheduledEmail much more stateless and testable. But, again, that’s effort.)

IDE Tooling

The good news: there is IDE support for Vue.

The bad news: it’s not very robust.

The same Vue component, in VSCode and PyCharm:

VSCode PyCharm

As you can see, the basics are there: syntax highlighting goes a long way, to be honest. But both IDEs have issues with formatting (PyCharm’s autoformat command will mangle the template code beyond recognition, for instance) and neither can parse the in-component CSS. Moreover, general navigational commands – symbolic recognition for components, autocompletion, and basic type-checking. It makes for a tough transition coming from React. (where the IDE tooling is just incredible)

Components are heavy

One of the things I really like about React is how easy it is to pluck out a component: components are just functions (or classes now, I guess!) so it’s just taking a chunk of code out, wrapping it in a render function, and basically calling it a day. Refactoring front-end code is relatively easy and light-weight, incentivizing developers to tease out lightweight and re-usable components.

Vue, though, is a different story.

Vue’s single file component paradigm is great for a lot of things, but it adds the friction of having to create a new file for each component.

That friction is compounded, too, by the requirement of registering components either in the global Vue namespace or in the components in which they’re invoked.

Obviously this is kind of trivial in the short term, but it creates a subtle disincentive to modularize and refactor your code.

I’d love a method of throwing multiple components into a single .vue file: that way, if I want to abstract out a EmailInput from a NewSubscriberModal, I can separate the actual code without needing to throw it in a new file and register that new file.


I feel like the most important question to ask after trying out a new piece of technology is: If you had to do it over again, would you still use it?

The answer for Vue is a resounding yes, even though there are a number of pain points that linger under the surface.

It feels obvious in use that Vue’s ecosystem is still growing, and hasn’t quite built out all the niceties that React has — which is tough in the short term but completely reasonable.

I have utmost faith that the Vue community is only going to keep growing and keep improving, and I’m excited for the next steps that the project takes.

Liked this post? Follow me!