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…
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
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