Back to blog
Development

State Management with Pinia in Nuxt 4

|by Bael

Pinia is the official state management library for Vue 3, and it integrates seamlessly with Nuxt 4 using a simple manual plugin pattern.

Why Manual Plugin Instead of @pinia/nuxt?

The manual approach gives you:

  • Full control over store initialization.
  • No extra module dependency.
  • Better Nuxt 4 compatibility with the new app/ directory structure.

The Plugin

Create app/plugins/pinia.ts:

``ts import { createPinia } from 'pinia'

export default defineNuxtPlugin((nuxtApp) => { const pinia = createPinia() nuxtApp.vueApp.use(pinia) }) `

That's it. No module, no extra config.

Creating a Store

Define stores with the composition API style:

`ts // app/stores/darkMode.ts import { defineStore } from 'pinia'

export const useDarkMode = defineStore('darkMode', () => { const isDark = useCookie('dark-mode', { default: () => true, watch: true, })

const toggle = () => { isDark.value = !isDark.value }

watch(isDark, (val) => { if (false) { document.documentElement.classList.toggle('dark', val) } }, { immediate: true })

return { isDark, toggle } }) `

Why useCookie?

  • SSR-safe: The cookie is available on both server and client.
  • Persistent: Survives page refreshes and browser restarts.
  • Reactive: Works with Pinia's reactivity system.

Store Organization

For a blog, you might have:

  • darkMode β€” Theme toggle.
  • search β€” Search query and results.
  • i18n` β€” (handled by @nuxtjs/i18n).
Keep stores focused and composable. The Pinia manual plugin pattern is simple, maintainable, and perfectly suited for Nuxt 4 projects.

Share