/pinia

🍍 Intuitive, type safe, light and flexible Store for Vue using the composition api with DevTools support

Primary LanguageTypeScriptMIT LicenseMIT

Pinia logo


npm package build status code coverage


Pinia

Intuitive, type safe and flexible Store for Vue

  • 💡 Intuitive
  • 🔑 Type Safe
  • ⚙️ Devtools support
  • 🔌 Extensible
  • 🏗 Modular by design
  • 📦 Extremely light

Pinia works both for Vue 2.x and Vue 3.x and you are currently on the branch that supports Vue 3.x. If you are looking for the version compatible with Vue 2.x, check the v1 branch.

Pinia is is the most similar English pronunciation of the word pineapple in Spanish: piña. A pineapple is in reality a group of individual flowers that join together to create a multiple fruit. Similar to stores, each one is born individually, but they are all connected at the end. It's also a delicious tropical fruit indigenous to South America.

Help me keep working on this project 💚

Gold Sponsors

Passionate People

Silver Sponsors

Vue Mastery Vuetify CodeStream

Bronze Sponsors

Storyblok Storyblok


FAQ

A few notes about the project and possible questions:

Q: Does this replace Vuex, is it its successor?

A: No, or at least that's not the main intention

Q: What about dynamic modules?

A: Dynamic modules are not type safe, so instead we allow creating different stores that can be imported anywhere

Roadmap / Ideas

  • Should the state be merged at the same level as actions and getters?
  • Allow grouping stores together into a similar structure and allow defining new getters (pinia) You can directly call useOtherStore() inside of a getter or action.
  • Getter with params that act like computed properties (@ktsn)

Installation

yarn add pinia@next
# or with npm
npm install pinia@next

Usage

Install the plugin

Create a pinia (the root store) and pass it to app:

import { createPinia } from 'pinia'

app.use(createPinia())

This will also add devtools support. Some features like time traveling and editing are still not supported because vue-devtools doesn't expose the necessary APIs yet.

Creating a Store

You can create as many stores as you want, and they should each exist in different files:

import { defineStore } from 'pinia'

export const useMainStore = defineStore({
  // name of the store
  // it is used in devtools and allows restoring state
  id: 'main',
  // a function that returns a fresh state
  state: () => ({
    counter: 0,
    name: 'Eduardo',
  }),
  // optional getters
  getters: {
    doubleCount() {
      return this.counter * 2
    },
    // use getters in other getters
    doubleCountPlusOne() {
      return this.doubleCount * 2 + 1
    },
  },
  // optional actions
  actions: {
    reset() {
      // `this` is the store instance
      this.counter = 0
    },
  },
})

defineStore returns a function that has to be called to get access to the store:

import { useMainStore } from '@/stores/main'

export default defineComponent({
  setup() {
    const main = useMainStore()

    return {
      // gives access to the whole store
      main,
      // gives access only to specific state
      state: computed(() => main.counter),
      // gives access to specific getter; like `computed` properties
      doubleCount: computed(() => main.doubleCount),
    }
  },
})

Documentation

To learn more about Pinia, check its documentation.

License

MIT