Dylan Tientcheu I build experiences to make your everyday life simpler.

Do you really need Vuex?

6 min read 1751

Vuex Logo Over a Field Background

Vue is already established as a major JavaScript framework. This is due to a multitude of reasons, ranging from its smooth developer experience to its extensive ecosystem. Vue’s core ecosystem and tooling is particularly admirable and is also what makes it eligible to be called a full-fledged framework.

Vue was built to be versatile, however, this versatility is very often misinterpreted by newcomers and certain seasoned developers, which tend to include a lot of tools because they think they may “need them later”. In reality, those tools are not always needed. Therefore, it is very important to understand how a tool can benefit us before adding it, or else it may turn into a disadvantage rather than something helpful.

We will now take a look at the core flux library in Vue.js: Vuex.

Vuex is the state management system in Vue.js. It is a centralized store that follows strict rules in order to help manage the state of all the components present in your Vue application.

Sounds extremely important. right? In reality, it’s a powerful tool that may or may not be helpful depending on the use case.

Why would you need Vuex?

Vuex is a state management system. So, to understand what Vuex does, you should first have a good grasp on the concept of state in an SPA and how it interacts with the other elements.

Actions, State, and View Have a Circular Relationship

Basically, the state is the data your components rely on. For example, the todos on your todos list, or the posts on a blog. This data is called the state, and each Vue component is allowed to have one.

As your app grows, there might be a significant increase in components. If you do not use a state management library like Vuex, each of these components will manage their own state by leveraging the Vue.js APIs designed for that purpose.

The Vue.js Component Tree

We made a custom demo for .
No really. Click here to check it out.

Keep in mind that Vue keeps a treelike component architecture as shown above, and also enables parent-child communication through props and child-parent communication via events. You can imagine how hard it may be if two distant sibling components need to react to the same data change — we will need to pass the data from child to parent til we reach the closest ancestor, then from that ancestor to the specific child (see the highlighted components on the figure above).

This is very laborious and error-prone.

That is exactly where Vuex comes in. Vuex does the job of abstracting a whole module’s state and keeping it in a centralized store, which follows Vuex’s state management pattern and communicates with your components accordingly.

That is why it is often referred to as “the single source of truth”. Though Vuex is aliased like this, that doesn’t alter the fact that components can still have their own states. You can decide to share these states with other components.

Sharing States With Components in Vuex

Now that you understand why we may need a state management system like Vuex, we can go ahead and make this bold assumption: there are only 2 major factors that determine whether or not you should manage state using Vue.

App size

People often say “as your app grows, you’ll need Vuex”. Actually, it depends on the way it grows. Your app may grow but your data flow stays nuclear (i.e parent-child and close siblings).

Eventually, you can use to props and events to share this data without having to add Vuex and the boilerplate that comes wtihit.

On the other hand, as soon as you notice that your components need to have an abstract data source, it’s wise to stop using props and events and resort to Vuex. This saves you an enormous amount of time, because the later you switch to Vuex, the more you’ll need to refactor.

Logic & data complexity

Sometimes we need to separate the implementation of a certain complex logic from our components, especially if this logic is related to other components in our system. A great example of this use case is authentication.

Vuex is a popular way to handle a complex app’s authentication in Vue. With Vuex, you’re able to handle the token’s availability and access controls and route blocks throughout your app. Mutations, getters, and setters assist with this task.

This pattern allows you to entirely separate the authentication logic from the app’s logic, while keeping your authentication flow traceable and your data accessible.

Vuex also eases unit testing on your whole app, which may be helpful if your app grows in complexity, making your state difficult to manage. However, you can absolutely complete testing without ever using Vuex.

When exactly would I need Vuex?

Here’s a funny quote by Dan Abramov:

Flux libraries are like eyeglasses: you’ll know when you need them.

This is a very true statement. However, some say it’s possible to notice too late that you need a flux library. Unfortunately, this will force you to introduce a complex flow to an already complex application.

Based on the two major factors I cited above (app size and data complexity), I created this little flow chart to help developers decide right from the project planning step if they will need Vuex to supercharge their app:

The Vuex Decision Map

There’s also a section in the Vuex docs that briefly explains when you should probably use Vuex.

Why would you skip out on Vuex?

When you create a new Vue.js app using the Vue-CLI, it doesn’t bug you by asking if you need a state management system. It just doesn’t include it. Though it’s extremely versatile, Vue.js aims to be very approachable and tries to make your new project as simple as possible.

A major reason people avoid Vuex is that Vuex is verbose. It needs to be — it has to follow a pattern in order to ensure that changes to your state happen on purpose. Below is a basic todo component that uses Vuex, compared to another that doesn’t:

Comparing Todo component With and Without Vuex

The code above shows how cumbersome your code will become when using Vuex to manage your state in a very simple app. In cases like this one, it’s best to skip out on Vuex and resort to props and events or another simple state management pattern.

How to skip out on Vuex

While working on a medium to small app, you have a handful of options you can explore if you don’t want to get entangled into Vuex’s verbosity. Some of these methods require you to write simple state management from scratch, and others require using 3rd party libraries. You get to use what works best for you depending on the way you want to structure your code.

Other flux libraries

It’s not a bad idea to use another flux library besides Vuex. Though they may serve the same purpose, they often differ in usage. Some may provide less boilerplate compared to Vuex, which may fit your use case.

GitHub – posva/pinia: 🍍 Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support

Intuitive, type safe and flexible Store for Vue Pinia works both for Vue 2.x and Vue 3.x. It requires Vue 2 with the latest @vue/composition-api or Vue ^3.2.0-0. Pinia is the most similar English pronunciation of the word pineapple in Spanish: piña.

GitHub – andy-piccalilli/beedle: A tiny library inspired by Redux & Vuex to help you manage state in your JavaScript apps

A tiny library inspired by Redux & Vuex to help you manage state in your JavaScript apps – GitHub – andy-piccalilli/beedle: A tiny library inspired by Redux & Vuex to help you manage state in your JavaScript apps

GitHub – alexander-heimbuch/redux-vuex: Redux bindings for VueJS inspired by Vuex.

Redux bindings for VueJS inspired by Vuex. Redux and vuex are really hard to compare. Vuex is a state management pattern that clearly defines each subject of the state lifecycle. For most of the projects this helps a lot structuring your application but it also leaves a large architectural footprint.

GitHub – andrewcourtice/harlem: Simple, unopinionated, lightweight and extensible state management for Vue 3

Simple, unopinionated, lightweight and extensible state management for Vue 3. Head over to harlemjs.com to get started or take a look at the demo to see it in action. Harlem has a simple functional API for creating, reading and mutating state.

GitHub – mediv0/v-bucket: 📦 Fast, Simple, and Lightweight State Manager for Vue 3.0 built with composition API, inspired by Vuex.

NPM STATUS: 📦 Fast, Simple, and Lightweight State Management for Vue 3.0 built with composition API, inspired by Vuex. Running the examples: install this package from NPM: $ npm install @mediv0/v-bucket or yarn: $ yarn add @mediv0/v-bucket first you need to create your bucket.

Flux from scratch

I’d recommend that anyone pick Vuex rather than following this method, because realistically you’ll just end up recreating Vuex. However, If you ever need a “custom” source of truth, you can also implement one yourself using the Vue.reactive method.

Keep in mind that for it to be a reliable source of truth, changes should occur only on the basis of a mutation, or else you’ll find yourself with untraceable bugs.

Shared State Built From Scratch

In its docs, Vue provides a little guide to help developers create their own centralized state management system.

Event bus

Vue also enables you to pass data throughout your app via a global event bus. You can read this article for a detailed tutorial on how to do this: https://blog.logrocket.com/using-event-bus-in-vue-js-to-pass-data-between-components/.

If you are using Vue 3, it’s a good idea to use a third party library like tiny-emitter or mitt to act as your event hub as suggested in the docs.

Composition API

Vue’s composition API’s motivation is to enable a better logic reuse and code organization in Vue apps. The composition API brings a modular pattern in Vue that enables you to flexibly compose your component’s logic.

With this elegant pattern, as explained by Andrej Galuf, it is possible to use the composition API as a store. You can compose a function that will later serve as your shared store. This will significantly reduce the boilerplate on a smaller app as compared to what Vuex may bring.

// @/services/counter.js
import { ref, computed } from '@vue/composition-api'
const count = ref(0)
export const getCount = computed(() => count.value)
export const increment = () => count.value += 1
// @/components/ComponentA.vue
<template>
    <div id="component-a">
        <button @click="increment()">Increment Counter</button>
    </div>
</template>

<script>
import { createComponent } from '@vue/composition-api'
import { increment } from '@/services/click-counter'

export default createComponent({
    setup() {
        return {
            increment
        }
    }
})
</script>
// @/components/ComponentB.vue
<template>
    <div id="component-b">
        Clicks: {{ getCount }}
    </div>
</template>

<script lang="ts">
import { createComponent } from '@vue/composition-api'
import { getCount } from '@/services/click-counter'

export default createComponent({
    setup() {
        return {
            getCount
        }
    }
})
</script>

Plugins

Vuex also has plugins that may help simplify the boilerplate. For example, we have the Vuex-pathify plugin, which helps you access deep properties in the state without using the getters property — you can do so with a path. For example, you can use [email protected] . Vuex pathify also enables you to set up mutations with a single path.

GitHub – davestewart/vuex-pathify: Vue / Vuex plugin providing a unified path syntax to Vuex stores

Pathify makes working with Vuex easy, with a declarative, state-based, path syntax: Paths can reference any module, property or sub-property: Pathify’s aim is to simplify the overall Vuex development experience by abstracting away Vuex’s complex setup and reliance on manually-written code.

Conclusion

There’s no doubt that Vuex is a great tool. However, with great power comes great responsibility. One of these responsibilities is understanding its power and deciding to leverage it or not at the cost of having a more complex codebase.

Most of the simple applications out there are fine with Vue’s event and props data communication pattern. These apps will tend to become much more complex if we add Vuex. Besides, Vue.js offers great tools like the composition API and top tier reactivity, which could do the job in a much better and simpler way than Vuex.

Next time you are working on your awesome Vue project, be sure you actually need Vuex before adding it.

Experience your Vue apps exactly how a user does

Debugging Vue.js applications can be difficult, especially when there are dozens, if not hundreds of mutations during a user session. If you’re interested in monitoring and tracking Vue mutations for all of your users in production, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens in your Vue apps including network requests, JavaScript errors, performance problems, and much more. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred.

The LogRocket Vuex plugin logs Vuex mutations to the LogRocket console, giving you context around what led to an error, and what state the application was in when an issue occurred.

Modernize how you debug your Vue apps - .

Dylan Tientcheu I build experiences to make your everyday life simpler.

2 Replies to “Do you really need Vuex?”

  1. Excellent article. However I’m wondering if what I’m doing now is good enough for certain basic purposes at least. I’m using a config.js file that I import in my main.js and enter into the global “domain” via Vue.prototype (ie Vue.prototype.settings). Then I’ve been able use the data as ie. `{{ settings.companyName }}` in some of my templates. This is only meant for config constant data, and it seems to work fine but wondering if I should use Vuex anyhow.

Leave a Reply