Pinia
WARNING:
Pilot Phase: Adopt Pinia with caution.
This is a new technology at GitLab and we might not have all the necessary precautions and best practices in place yet.
If you're considering using Pinia please drop a message in the #frontend
internal Slack channel for evaluation.
Pinia is a tool for managing client-side state for Vue applications. Refer to the official documentation on how to use Pinia.
Best practices
Small stores
Prefer creating small stores that focus on a single task only. This is contrary to the Vuex approach which encourages you to create bigger stores.
Treat Pinia stores like cohesive components rather than giant state façades (Vuex modules).
Single file stores
Place state, actions, and getters in a single file.
Do not create 'barrel' store index files which import everything from actions.js
, state.js
and getters.js
.
If your store file gets too big it's time to consider splitting that store into multiple stores.
Use Option Stores
Pinia offers two types of store definitions: option and setup. Prefer the option type when creating new stores. This promotes consistency and will simplify the migration path from Vuex.
Before Pinia
flowchart TD
A[Store]
A --> B[State]
A --> C[Actions]
A --> D[Mutations]
A --> E[Getters]
B --> F[items]
B --> G[isLoadingItems]
B --> H[itemWithActiveForm]
B --> I[isSubmittingForm]
After Pinia
flowchart TD
A[Items Store]
A --> B[State]
A --> C[Actions]
A --> D[Getters]
B --> E[items]
B --> F[isLoading]
H[Form Store]
H --> I[State]
H --> J[Actions]
H --> K[Getters]
I --> L[activeItem]
I --> M[isSubmitting]
Migrating from Vuex
Decide what your primary state manager should be first. Proceed with this guide if Pinia was your choice.
Follow the official Vuex migration guide.
Try to split all your migrations into two steps:
- Refactor just the Vuex API: Don't change the store structure, make sure it works in Pinia (example).
- Refactor the structure: Split your store into multiple smaller, single purpose stores.
Automated migration using codemods
You can use ast-grep codemods to simplify migration from Vuex to Pinia.
- Install ast-grep on your system before proceeding.
- Run
scripts/frontend/codemods/vuex-to-pinia/migrate.sh path/to/your/store
The codemods will migrate actions.js
, mutations.js
and getters.js
located in your store folder.
Manually scan these files after running the codemods to ensure they are properly migrated.
Vuex specs can not be automatically migrated, migrate them by hand.
Vuex module calls are replaced using Pinia conventions:
-
dispatch('anotherModule/action', ...args, { root: true })
→useAnotherModule().action(...args)
-
dispatch('action', ...args, { root: true })
→useRootStore().action(...args)
-
rootGetters['anotherModule/getter']
→useAnotherModule().getter
-
rootGetters.getter
→useRootStore().getter
-
rootState.anotherModule.state
→useAnotherModule().state
If you have not yet migrated a dependent module (useAnotherModule
and useRootStore
in the examples above) you can create a temporary dummy store.
Use the guidance below to migrate Vuex modules.
Migrating stores with nested modules
It is not trivial to iteratively migrate stores with nested modules that have dependencies between them. In such cases prefer migrating nested modules first:
- Create a Pinia store counterpart of the nested Vuex store module.
- Create a placeholder Pinia 'root' store for root module dependencies if applicable.
- Copy and adapt existing tests for the migrated module.
- Do not use migrated modules yet.
- Once all the nested modules are migrated you can migrate the root module and replace the placeholder store with the real one.
- Replace Vuex store with Pinia stores in components.