# Vue 3 Pinia vs Vuex: Modernes State Management und Interviewfragen 2026 > Pinia vs Vuex im direkten Vergleich: API-Design, TypeScript-Unterstützung, Performance, Migrationsstrategien und häufige Vue-Interviewfragen zum State Management 2026. - Published: 2026-04-23 - Updated: 2026-04-23 - Author: SharpSkill - Tags: vue, pinia, vuex, state-management, interview - Reading time: 9 min --- Pinia vs Vuex markiert den bedeutendsten Umbruch im Vue State Management seit der Veröffentlichung von Vue 3. Da Pinia 3 mittlerweile die offizielle Empfehlung darstellt und Vuex nur noch im Wartungsmodus gepflegt wird, ist das Verständnis der Unterschiede zwischen beiden Bibliotheken für Vue-Entwickler unverzichtbar — und ein häufiges Thema in technischen Vorstellungsgesprächen. > **Kernaussage** > > Pinia ist die offizielle State-Management-Lösung für Vue 3. Vuex 5 wurde eingestellt, und Evan You hat Pinia als das de facto Vuex 5 bezeichnet. Alle neuen Vue-3-Projekte sollten Pinia 3 verwenden. ## Pinia vs Vuex: Grundlegende Architekturunterschiede Der fundamentale Architekturunterschied zwischen Pinia und Vuex liegt in der Art und Weise, wie State-Mutationen ablaufen. Vuex erzwingt einen strikten unidirektionalen Datenfluss: Komponenten dispatchen Actions, Actions committen Mutations, und Mutations verändern den State. Pinia entfernt die Mutation-Schicht vollständig und ermöglicht direkte State-Änderungen aus Actions oder sogar aus Komponenten heraus. Diese Vereinfachung reduziert den Boilerplate-Code in den meisten Codebasen um etwa 40 %. Während Vuex vier Konzepte erfordert (State, Getters, Mutations, Actions), kommt Pinia mit drei aus (State, Getters, Actions). | Feature | Pinia 3 | Vuex 4 | |---------|---------|--------| | Mutations | Keine (direkte State-Änderungen) | Erforderlich für State-Änderungen | | TypeScript | Volle Inferenz, keine Augmentation | Manuelle Typ-Augmentation nötig | | Store-Architektur | Mehrere flache Stores | Einzelner Store mit verschachtelten Modulen | | Composition API | Native Unterstützung | Options-API-basiert | | Bundle-Größe | ~1 KB gzipped | ~6 KB gzipped | | Vue Devtools | Volle Unterstützung (v7) | Volle Unterstützung | | SSR | Integriert | Konfiguration erforderlich | | Hot Module Replacement | Integriert | Manuelle Einrichtung | ## Stores definieren: Options API vs Setup-Syntax Pinia bietet zwei Syntaxvarianten für die Store-Definition. Die Options-Syntax orientiert sich an der Vuex-Struktur und erleichtert die Migration. Die Setup-Syntax nutzt die Composition API von Vue 3 für maximale Flexibilität. ```typescript // stores/counter-options.ts import { defineStore } from 'pinia' // Options Store Syntax — vertraut für Vuex-Entwickler export const useCounterStore = defineStore('counter', { state: () => ({ count: 0, lastUpdated: null as Date | null, }), getters: { // Getters erhalten state als erstes Argument mit voller Typ-Inferenz doubleCount: (state) => state.count * 2, isPositive(): boolean { // Zugriff auf andere Getters über `this` return this.count > 0 }, }, actions: { increment() { // Direkte State-Mutation — kein commit() nötig this.count++ this.lastUpdated = new Date() }, async fetchCount(id: string) { // Asynchrone Actions funktionieren ohne zusätzliche Konfiguration const response = await fetch(`/api/counters/${id}`) const data = await response.json() this.count = data.count }, }, }) ``` Die Options-Syntax bildet Vuex-Konzepte direkt ab. State ersetzt Vuex State, Getters bleiben Getters, und Actions übernehmen sowohl Vuex Actions als auch Mutations. ```typescript // stores/counter-setup.ts import { defineStore } from 'pinia' import { ref, computed } from 'vue' // Setup Store Syntax — identische Muster wie Composition API export const useCounterStore = defineStore('counter', () => { // ref() wird zu State const count = ref(0) const lastUpdated = ref(null) // computed() wird zu Getters const doubleCount = computed(() => count.value * 2) const isPositive = computed(() => count.value > 0) // Funktionen werden zu Actions function increment() { count.value++ lastUpdated.value = new Date() } async function fetchCount(id: string) { const response = await fetch(`/api/counters/${id}`) const data = await response.json() count.value = data.count } // Alle State-Eigenschaften, Getters und Actions müssen zurückgegeben werden return { count, lastUpdated, doubleCount, isPositive, increment, fetchCount } }) ``` Die Setup-Syntax bietet volle Flexibilität: Watchers, Composable-Wiederverwendung und bedingte Logik funktionieren innerhalb der Store-Definition auf natürliche Weise. Der Nachteil: Jede reaktive Eigenschaft und Methode muss explizit zurückgegeben werden. ## TypeScript-Integration: Wo Pinia Vuex übertrifft Die TypeScript-Unterstützung ist der Bereich, in dem Pinia eindeutig gewinnt. Vuex 4 erfordert manuelle Typ-Augmentation über Modul-Deklarationen, und bei komplexen verschachtelten Modulen wird die Typ-Inferenz brüchig. Pinia leitet Typen automatisch aus der Store-Definition ab. ```typescript // Vuex 4 — manuelle Typ-Augmentation erforderlich import { Store } from 'vuex' declare module 'vuex' { interface State { counter: { count: number lastUpdated: Date | null } } } // Zugriff auf State erfordert Type Assertions oder eigene Helfer const count = (store.state as { counter: { count: number } }).counter.count ``` ```typescript // Pinia — volle Typ-Inferenz, keine Konfiguration const counter = useCounterStore() // TypeScript erkennt counter.count als number // TypeScript erkennt counter.doubleCount als number // TypeScript erkennt counter.increment() als void // TypeScript erkennt counter.fetchCount() als Promise counter.increment() console.log(counter.doubleCount) ``` Pinia unterstützt außerdem generische Stores für wiederverwendbare Muster — eine Fähigkeit, die in Vuex erheblichen Boilerplate-Code erfordert. ## Composition API und Composable-Integration Pinia Setup Stores akzeptieren beliebige Vue Composables und ermöglichen leistungsstarke Muster wie gemeinsam genutzte VueUse-Utilitys oder router-abhängigen State. ```typescript // stores/search.ts import { defineStore } from 'pinia' import { ref, watch } from 'vue' import { useDebounceFn } from '@vueuse/core' import { useRoute } from 'vue-router' export const useSearchStore = defineStore('search', () => { const route = useRoute() const query = ref('') const results = ref([]) const isLoading = ref(false) // VueUse Composable direkt im Store verwendet const debouncedSearch = useDebounceFn(async (term: string) => { if (!term.trim()) { results.value = [] return } isLoading.value = true try { const res = await fetch(`/api/search?q=${encodeURIComponent(term)}`) results.value = await res.json() } finally { isLoading.value = false } }, 300) // Watcher synchronisiert URL-Query-Parameter mit Store-State watch(() => route.query.q, (q) => { if (typeof q === 'string') { query.value = q debouncedSearch(q) } }) function setQuery(term: string) { query.value = term debouncedSearch(term) } return { query, results, isLoading, setQuery } }) ``` Dieses Muster ist in Vuex ohne Umwege nicht möglich. Vuex-Module können in ihrer Definition keine Composables, Watchers oder Router-Hooks verwenden. Die Store-Logik muss zwischen dem Vuex-Modul und externen Hilfsfunktionen aufgeteilt werden. ## Store-Kommunikation und Store-übergreifende Referenzen Vuex verwendet einen einzelnen Root-Store mit namespaced Modulen. Der Zugriff auf State über Module hinweg erfordert umständliche `rootState`- und `rootGetters`-Parameter. Pinia Stores sind bewusst unabhängig gestaltet, und die store-übergreifende Kommunikation erfolgt über direkte Imports. ```typescript // stores/cart.ts import { defineStore } from 'pinia' import { useProductStore } from './products' import { useAuthStore } from './auth' import { ref, computed } from 'vue' export const useCartStore = defineStore('cart', () => { const items = ref([]) const total = computed(() => { // Zugriff auf einen anderen Store durch Aufruf seines Composable const productStore = useProductStore() return items.value.reduce((sum, item) => { const product = productStore.getById(item.productId) return sum + (product?.price ?? 0) * item.quantity }, 0) }) async function checkout() { const auth = useAuthStore() if (!auth.isAuthenticated) { throw new Error('Authentifizierung erforderlich') } // Checkout-Logik } return { items, total, checkout } }) ``` Diese flache Store-Architektur vermeidet die tief verschachtelten Modulbäume, die große Vuex-Anwendungen schwer navigierbar und refaktorierbar machen. ## Migration von Vuex 4 zu Pinia 3 Die Migration von Vuex zu Pinia kann Modul für Modul erfolgen. Beide Bibliotheken können während der Übergangsphase koexistieren. Die empfohlene Strategie: mit Blatt-Modulen beginnen (Stores, von denen keine anderen Module abhängen) und sich nach innen vorarbeiten. > **Migrationskompatibilität** > > Pinia und Vuex können in derselben Anwendung parallel betrieben werden. Pinia neben Vuex installieren, ein Modul nach dem anderen migrieren und Vuex erst entfernen, wenn alle Module konvertiert sind. ```typescript // Vorher: Vuex-Modul // store/modules/user.ts const userModule = { namespaced: true, state: () => ({ profile: null as UserProfile | null, preferences: {} as UserPreferences, }), mutations: { SET_PROFILE(state, profile: UserProfile) { state.profile = profile }, UPDATE_PREFERENCES(state, prefs: Partial) { state.preferences = { ...state.preferences, ...prefs } }, }, actions: { async fetchProfile({ commit }) { const profile = await api.getProfile() commit('SET_PROFILE', profile) }, async updatePreferences({ commit }, prefs: Partial) { await api.updatePreferences(prefs) commit('UPDATE_PREFERENCES', prefs) }, }, getters: { isLoggedIn: (state) => state.profile !== null, displayName: (state) => state.profile?.name ?? 'Guest', }, } ``` ```typescript // Nachher: Pinia Store // stores/user.ts import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { api } from '@/lib/api' export const useUserStore = defineStore('user', () => { const profile = ref(null) const preferences = ref({}) const isLoggedIn = computed(() => profile.value !== null) const displayName = computed(() => profile.value?.name ?? 'Guest') async function fetchProfile() { profile.value = await api.getProfile() } async function updatePreferences(prefs: Partial) { await api.updatePreferences(prefs) Object.assign(preferences.value, prefs) } return { profile, preferences, isLoggedIn, displayName, fetchProfile, updatePreferences } }) ``` Das Migrationsmuster ist konsistent: Mutations verschmelzen mit direkten Zuweisungen in Actions, `commit()`-Aufrufe entfallen, und `mapState`/`mapGetters`-Helfer werden durch Destrukturierung des Store-Composable ersetzt. ## SSR State Hydration mit Pinia und Nuxt 4 Server-Side Rendering bringt Komplexität für das State Management mit sich. Pinia übernimmt die SSR-State-Serialisierung und Hydration in [Nuxt 4](https://nuxt.com/docs/getting-started/state-management) automatisch, während Vuex eine manuelle `window.__INITIAL_STATE__`-Behandlung erfordert. > **SSR-Fallstrick** > > Setup Stores, die Composables wie `useRoute()` oder `useFetch()` verwenden, müssen im SSR-Kontext sorgfältig behandelt werden. Diese Composables dürfen nur während der Setup-Phase aufgerufen werden, niemals innerhalb asynchroner Callbacks. ```typescript // stores/products.ts — SSR-sicherer Pinia Store für Nuxt 4 import { defineStore } from 'pinia' export const useProductStore = defineStore('products', { state: () => ({ items: [] as Product[], selectedCategory: 'all', }), actions: { async fetchProducts() { // useFetch ist Nuxt-spezifisch — $fetch für Store Actions verwenden this.items = await $fetch('/api/products', { query: { category: this.selectedCategory }, }) }, }, getters: { getById: (state) => (id: string) => state.items.find((item) => item.id === id), filteredCount: (state) => state.items.filter((p) => p.inStock).length, }, }) ``` Nuxt 4 serialisiert den Pinia-State automatisch auf dem Server und hydriert ihn auf dem Client. Keine manuelle `replaceState()`- oder Dehydrierungslogik erforderlich. ## Performance-Vergleich und Bundle-Auswirkung Pinias Footprint von ~1 KB gzipped ist etwa sechsmal kleiner als die ~6 KB von Vuex. In Anwendungen mit Code Splitting sind Pinia Stores tree-shakable: Nicht verwendete Stores und ihre Abhängigkeiten werden aus Produktions-Bundles ausgeschlossen. Laufzeit-Performance-Unterschiede sind für die meisten Anwendungen vernachlässigbar. Beide Bibliotheken verwenden unter der Haube das Reaktivitätssystem von Vue. Der praktische Performance-Gewinn ergibt sich aus reduziertem Boilerplate, der zu weniger Re-Renders führt, die durch zu breite State-Subscriptions verursacht werden — Pinias flaches Store-Modell fördert granulare Stores, was bedeutet, dass Komponenten weniger State abonnieren. Mit der Einführung des [Vapor Mode](https://vuejs.org/guide/extras/reactivity-in-depth.html) in Vue 3.6 profitieren sowohl Pinia als auch Vuex von der schnelleren Rendering-Pipeline. Allerdings ist Pinia durch seine engere Integration mit der Composition API besser für Vapor-Mode-Optimierungen aufgestellt. ## Häufige Vue State Management Interviewfragen In technischen Vorstellungsgesprächen wird häufig Wissen zum State Management geprüft. Hier sind die Fragen, die 2026 am häufigsten in Vue-Entwickler-Interviews gestellt werden. **F: Warum wurde die Mutation-Schicht von Vuex in Pinia entfernt?** Mutations existierten in Vuex, um Time-Travel-Debugging in den DevTools zu ermöglichen. Jede State-Änderung musste über eine synchrone Mutation laufen, damit die DevTools Snapshots aufzeichnen konnten. Pinia erreicht dieselbe Debugging-Fähigkeit, indem State-Änderungen auf reaktiver Ebene verfolgt werden, wodurch die explizite Mutation-Schicht überflüssig wird. Das Ergebnis: weniger Boilerplate, gleiche Debugging-Möglichkeiten. **F: Wann sollte ein Setup Store einem Options Store vorgezogen werden?** Setup Stores sind die bessere Wahl, wenn der Store Composables (`useRoute`, `useDebounceFn`), komplexe Watchers oder gemeinsam genutzte Logik aus externen Composable-Funktionen benötigt. Options Stores eignen sich gut für unkomplizierten CRUD-State mit einfachen Getters. In der Praxis sind Setup Stores in Produktions-Codebasen häufiger, da sie die Muster der Composition API in Komponenten widerspiegeln. **F: Wie behandelt Pinia die Reaktivität bei verschachtelten Objekten?** Pinia verwendet `reactive()` von Vue für das gesamte State-Objekt und `ref()` für einzelne Eigenschaften in Setup Stores. Deep Reactivity gilt standardmäßig — Änderungen an verschachtelten Objekten werden automatisch verfolgt. Für performance-kritische Fälle mit großen Datensätzen kann `shallowRef()` die Deep Reactivity deaktivieren. **F: Store-zu-Store-Abhängigkeiten in Pinia vs Vuex erklären.** In Vuex erfolgt der modulübergreifende Zugriff über `rootState`- und `rootGetters`-Parameter in Actions, was zu impliziter Kopplung führt. In Pinia importieren Stores einander direkt über `useOtherStore()`-Aufrufe. Das macht Abhängigkeiten explizit und ermöglicht TypeScript, sie zur Compile-Zeit zu überprüfen. Zirkuläre Abhängigkeiten funktionieren in Pinia, solange sie nicht während der initialen Setup-Phase aufgerufen werden. **F: Was passiert mit dem Pinia-State während der SSR-Hydration?** Während des SSR serialisiert Pinia alle aktiven Store-States zu JSON und bettet das Ergebnis in den HTML-Payload ein. Auf dem Client hydriert Pinia jeden Store, bevor Komponenten gemountet werden. Jeder State, der während des serverseitigen Renderings gesetzt wurde, ist sofort auf dem Client verfügbar, ohne dass API-Aufrufe dupliziert werden müssen. In Nuxt 4 ist dieser Prozess vollständig automatisiert. Für weitere Vue- und Nuxt-Interviewvorbereitung bieten sich das [State Management Interview-Modul](/technologies/vue-nuxt/interview-questions/nuxt-state-management) oder das [Vue Composables Modul](/technologies/vue-nuxt/interview-questions/vue-composables) an. ## Fazit - Pinia 3 ist die offizielle Vue State Management Bibliothek — Vuex befindet sich im Wartungsmodus ohne geplante v5-Veröffentlichung - Die Mutation-Schicht ist verschwunden: Pinia Actions ändern den State direkt und reduzieren Boilerplate um ~40 % - TypeScript-Inferenz funktioniert in Pinia sofort ohne jegliche Augmentation, im Gegensatz zu Vuex's manuellen Typ-Deklarationen - Setup Stores integrieren sich nahtlos mit der Vue 3 Composition API und ermöglichen Composable-Wiederverwendung sowie Watchers innerhalb von Stores - Flache Store-Architektur ersetzt Vuex's verschachtelten Modulbaum und macht Store-übergreifende Kommunikation explizit und typsicher - Migration kann inkrementell erfolgen: Pinia und Vuex koexistieren und ermöglichen eine Modul-für-Modul-Konvertierung - SSR-Hydration ist in Nuxt 4 mit Pinia automatisch — keine manuelle Serialisierung nötig - Für alle neuen Vue-3-Projekte in 2026 ist Pinia die klare Wahl mit besserer Developer Experience, kleineren Bundles und stärkerer Ökosystem-Unterstützung --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/de/blog/vue-nuxt/vue-3-pinia-vs-vuex-state-management