← Back to list

Svelte Store vs Vuex:A Comparison of Lightweight State Management

In modern front-end frameworks, state management is a crucial component that helps organize and maintain application state. Svelte and…

Kevin · 2026-02-02 12:01 · 12 claps · 5.9 min read
#svelte #sveltekit #vuejs #vuex #javascript
Open on Medium ↗
Wiki topics: BIZ · Business Strategy 🌐 · Web Development 🔧 · Data Engineering

Svelte Store vs Vuex:A Comparison of Lightweight State Management

In modern front-end frameworks, state management is a crucial component that helps organize and maintain application state. Svelte and Vue.js use Svelte Store and Vuex respectively as their state management solutions. State management is a key concern in single-page applications (SPAs), especially in large-scale applications, where centralized state management makes the state easier to track and maintain. Both Svelte and Vue.js provide their own state management mechanisms, but they differ in design philosophy and implementation details.

Photo by Chris Ried on Unsplash

Photo by Chris Ried on Unsplash

Svelte Store

Svelte’s state management is built into the framework itself. It provides a “store” API for sharing state across components. Svelte Store can be categorized into three types: readable, writable, and derived.

Creating Stores

Readable Store

A readable store can only be subscribed to — it cannot be modified directly.

import { readable } from 'svelte/store';

const count = readable(0, set => {
  let latestCount = 0;
  const subscriber = count => {
    latestCount = count;
    set(latestCount);
  };
  return { subscribe: subscriber };
});

Writable Store

A writable store can both be subscribed to and modified.

import { writable } from 'svelte/store';

const count = writable(0);
count.set(1); // Set value
count.update(n => n + 1); // Update value

Derived Store

A derived store computes a new store based on other stores.

import { derived } from 'svelte/store';

const doubleCount = derived(count, $count => $count * 2);

Using Stores

Using a store in a Svelte component is straightforward — simply prefix the store name with $ to access its value.

<script>
  import { onMount } from 'svelte';
  import { count } from './store';
let localCount = $count;
  onMount(() => count.subscribe(value => localCount = value));
</script>
<h1>{localCount}</h1>
<button on:click={() => count.update(n => n + 1)}>Increment</button>

Vuex

Vuex is the official state management pattern and library for Vue.js. It uses a centralized store to manage the state of all components in an application and enforces rules to ensure state changes occur in a predictable way.

Creating a Store

First, install Vuex:

npm install vuex

Then create the store:

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment');
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2;
    }
  }
});

Using the Store

Use the store in a Vue component:

<template>
  <div>
    <h1>{{ doubleCount }}</h1>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';
export default {
  computed: {
    ...mapGetters(['doubleCount'])
  },
  methods: {
    ...mapActions(['increment'])
  }
};
</script>

Svelte Store: Managing Complex State

Svelte Store can manage more complex state, such as nested objects or arrays.

Example: Managing User Information

import { writable } from 'svelte/store';

const user = writable({
  name: 'Alice',
  email: 'alice@example.com',
  posts: []
});
function addUserPost(post) {
  user.update(u => ({
    ...u,
    posts: [...u.posts, post]
  }));
}
export { user, addUserPost };

Usage Example

<script>
  import { onMount } from 'svelte';
  import { user, addUserPost } from './store';
  let localUser = $user;
  onMount(() => user.subscribe(value => localUser = value));
  function addNewPost() {
    addUserPost({
      title: 'New Post',
      content: 'This is a new post.'
    });
  }
</script>
<h1>User: {localUser.name}</h1>
<h2>Email: {localUser.email}</h2>
<ul>
  {#each localUser.posts as post (post.title)}
    <li>{post.title}</li>
  {/each}
</ul>
<button on:click={addNewPost}>Add Post</button>

Combining Multiple Stores

You can combine multiple stores to create more complex state management logic.

Example: Combining Multiple Stores

import { writable } from 'svelte/store';

const count = writable(0);
const doubleCount = writable(0);
function updateCounts() {
  doubleCount.set($count * 2);
}
count.subscribe(updateCounts);
export { count, doubleCount };

Usage Example

<script>
  import { onMount } from 'svelte';
  import { count, doubleCount } from './store';

  let localCount = $count;
  let localDoubleCount = $doubleCount;
  onMount(() => {
    count.subscribe(value => localCount = value);
    doubleCount.subscribe(value => localDoubleCount = value);
  });
  function increment() {
    count.update(n => n + 1);
  }
</script>
<h1>Count: {localCount}</h1>
<h2>Double Count: {localDoubleCount}</h2>
<button on:click={increment}>Increment</button>

Vuex: Modular State Management

Vuex supports modular state management, allowing you to split the state into multiple modules, each with its own state, mutations, actions, and getters.

Example: Modular State Management

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
const userModule = {
  state: {
    name: 'Alice',
    email: 'alice@example.com',
    posts: []
  },
  mutations: {
    addPost(state, post) {
      state.posts.push(post);
    }
  },
  actions: {
    addPost({ commit }, post) {
      commit('addPost', post);
    }
  },
  getters: {
    allPosts(state) {
      return state.posts;
    }
  }
};
const store = new Vuex.Store({
  modules: {
    user: userModule
  }
});
export default store;

Usage Example

<template>
  <div>
    <h1>User: {{ user.name }}</h1>
    <h2>Email: {{ user.email }}</h2>
    <ul>
      <li v-for="post in user.allPosts" :key="post.title">{{ post.title }}</li>
    </ul>
    <button @click="addPost">Add Post</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';
export default {
  computed: {
    ...mapState('user', ['name', 'email', 'allPosts'])
  },
  methods: {
    ...mapActions('user', ['addPost'])
  }
};
</script>

Namespacing

In modular setups, you can use namespacing to avoid naming conflicts between states and methods.

Example: Using Namespaces

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
const userModule = {
  namespaced: true,
  state: {
    name: 'Alice',
    email: 'alice@example.com',
    posts: []
  },
  mutations: {
    addPost(state, post) {
      state.posts.push(post);
    }
  },
  actions: {
    addPost({ commit }, post) {
      commit('addPost', post);
    }
  },
  getters: {
    allPosts(state) {
      return state.posts;
    }
  }
};
const store = new Vuex.Store({
  modules: {
    user: userModule
  }
});
export default store;

Usage Example

<template>
  <div>
    <h1>User: {{ user.name }}</h1>
    <h2>Email: {{ user.email }}</h2>
    <ul>
      <li v-for="post in user.allPosts" :key="post.title">{{ post.title }}</li>
    </ul>
    <button @click="addPost">Add Post</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';
export default {
  computed: {
    ...mapState('user', ['name', 'email', 'allPosts'])
  },
  methods: {
    ...mapActions('user', ['addPost'])
  }
};
</script>

Practical Examples

Svelte Store Practical Example

Suppose we need to implement a simple to-do list application.

Store File (store.js):

import { writable } from 'svelte/store';

const todos = writable([
  { id: 1, text: 'Learn Svelte', done: false },
  { id: 2, text: 'Build an app', done: false }
]);
function addTodo(text) {
  todos.update(todos => [
    ...todos,
    { id: Date.now(), text, done: false }
  ]);
}
function toggleTodo(id) {
  todos.update(todos =>
    todos.map(todo =>
      todo.id === id ? { ...todo, done: !todo.done } : todo
    )
  );
}
function removeTodo(id) {
  todos.update(todos => todos.filter(todo => todo.id !== id));
}
export { todos, addTodo, toggleTodo, removeTodo };

Main Component (App.svelte):

<script>
  import { onMount } from 'svelte';
  import { todos, addTodo, toggleTodo, removeTodo } from './store';
 let newTodoText = '';
  let localTodos = $todos;
  onMount(() => {
    todos.subscribe(value => localTodos = value);
  });
  function handleAddTodo() {
    if (newTodoText.trim()) {
      addTodo(newTodoText);
      newTodoText = '';
    }
  }
  function handleToggleTodo(id) {
    toggleTodo(id);
  }
  function handleRemoveTodo(id) {
    removeTodo(id);
  }
</script>
<main>
  <h1>To-Do List</h1>
  <input type="text" bind:value={newTodoText} placeholder="Add a new to-do" />
  <button on:click={handleAddTodo}>Add</button>
  <ul>
    {#each localTodos as todo (todo.id)}
      <li>
        <input
          type="checkbox"
          checked={todo.done}
          on:change={() => handleToggleTodo(todo.id)}
        />
        <span style={todo.done ? 'text-decoration: line-through;' : ''}>
          {todo.text}
        </span>
        <button on:click={() => handleRemoveTodo(todo.id)}>Remove</button>
      </li>
    {/each}
  </ul>
</main>

Vuex Practical Example

Similarly, we implement a to-do list application using Vuex for state management.

Store File (store.js):

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);
const store = new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'Learn Vue', done: false },
      { id: 2, text: 'Build an app', done: false }
    ]
  },
  mutations: {
    addTodo(state, text) {
      state.todos.push({ id: Date.now(), text, done: false });
    },
    toggleTodo(state, id) {
      const todo = state.todos.find(todo => todo.id === id);
      if (todo) {
        todo.done = !todo.done;
      }
    },
    removeTodo(state, id) {
      state.todos = state.todos.filter(todo => todo.id !== id);
    }
  },
  actions: {
    addTodo({ commit }, text) {
      commit('addTodo', text);
    },
    toggleTodo({ commit }, id) {
      commit('toggleTodo', id);
    },
    removeTodo({ commit }, id) {
      commit('removeTodo', id);
    }
  },
  getters: {
    todos: state => state.todos
  }
});
export default store;

Main Component (App.vue):

<template>
  <main>
    <h1>To-Do List</h1>
    <input type="text" v-model="newTodoText" placeholder="Add a new to-do" />
    <button @click="addTodo">Add</button>
    <ul>
      <li v-for="todo in todos" :key="todo.id">
        <input
          type="checkbox"
          :checked="todo.done"
          @change="toggleTodo(todo.id)"
        />
        <span :style="{ 'text-decoration': todo.done ? 'line-through' : 'none' }">
          {{ todo.text }}
        </span>
        <button @click="removeTodo(todo.id)">Remove</button>
      </li>
    </ul>
  </main>
</template>

<script>
import { mapState, mapActions } from 'vuex';
export default {
  data() {
    return {
      newTodoText: ''
    };
  },
  computed: {
    ...mapState(['todos'])
  },
  methods: {
    ...mapActions(['addTodo', 'toggleTodo', 'removeTodo'])
  }
};
</script>

Comparative Analysis

Performance

  • Svelte Store: Since Svelte eliminates unnecessary code at compile time, it achieves very high performance. Store changes directly trigger re-renders of relevant components.
  • Vuex: Although Vuex is also reactive, it is built on Vue’s reactivity system, which may introduce some overhead in certain scenarios.

Learning Curve

  • Svelte Store: For developers familiar with JavaScript, Svelte Store’s API is intuitive and easy to understand.
  • Vuex: Vuex introduces richer concepts — including state, mutations, actions, and getters — which may require some time for beginners to adapt to.

Ecosystem

  • Svelte Store: Svelte’s ecosystem is relatively smaller, but its core library provides sufficient functionality.
  • Vuex: As part of the Vue.js ecosystem, Vuex benefits from a large community and a rich plugin ecosystem.

Applicable Scenarios

  • Svelte Store: Ideal for small-to-medium projects or applications with high performance requirements.
  • Vuex: Best suited for large, complex applications that require strict state management workflows.

메타데이터
post_id
17ccccc1aaa5
slug
svelte-store-vs-vuex-a-comparison-of-lightweight-state-management-17ccccc1aaa5
url
https://medium.com/@tianyaschool/svelte-store-vs-vuex-a-comparison-of-lightweight-state-management-17ccccc1aaa5
canonical_url
https://medium.com/@tianyaschool/svelte-store-vs-vuex-a-comparison-of-lightweight-state-management-17ccccc1aaa5
author_url
https://medium.com/@tianyaschool
status
ok
fetched_at
2026-06-22 00:13:37