svelte-store
A Pinia-style state management library for Svelte 5, built on svelte/store, providing type-safe global state management.
Features
- Pinia-style API (defineStore, supports Options API and Setup style)
- Built on svelte/store, supports $store auto-subscription
- Plugin system (persistence / logging, etc.)
- Full TypeScript type inference
- Zero extra dependencies
- Compatible with CommonJS and ES Modules
Installation
npm Install
# npm
npm install @free-walk/svelte-store
# cnpm(国内镜像)
cnpm install @free-walk/svelte-store
# yarn
yarn add @free-walk/svelte-store
# pnpm
pnpm add @free-walk/svelte-store Peer Dependencies
Make sure the following dependencies are installed:
npm install svelte ES Module Import
import { defineStore, mapState, mapActions } from '@free-walk/svelte-store' CommonJS Require
const { defineStore, mapState, mapActions } = require('@free-walk/svelte-store') CDN Usage
You can also use it directly via CDN (for quick prototyping or online demos):
<script src="https://unpkg.com/@free-walk/svelte-store@1.2.0/dist/svelte-store.iife.js"></script>Quick Start
// stores/counter.ts
import { defineStore } from '@free-walk/svelte-store'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
})
// 组件中使用
<script>
import { useCounterStore } from '../stores/counter'
const counter = useCounterStore()
</script>
<p>count: {$counter.count}</p>
<p>double: {$counter.double}</p>
<button onclick={() => counter.increment()}>+1</button>defineStore
Factory function for creating a Store, supports two styles.
Function Signature
// Options API 风格
defineStore(id: string, options: StoreOptions): () => StoreInstance
// Setup 风格
defineStore(id: string, setup: () => SetupReturn): () => StoreInstance Param
| Param | Type | Description |
|---|---|---|
id | string | Unique identifier for the Store |
options | StoreOptions | Options API configuration object |
setup | () => object | Setup function, returns state and methods |
Options API
Define a Store using Pinia-like Options API style.
StoreOptions
| Property | Type | Description |
|---|---|---|
state | () => object | Factory function returning initial state |
getters | Record<string, (state) => any> | Computed properties, receives state as argument |
actions | Record<string, Function> | Methods, this points to the store state |
Example
export const useTodoStore = defineStore('todo', {
state: () => ({
items: [] as string[],
filter: 'all' as 'all' | 'done' | 'pending',
}),
getters: {
count: (state) => state.items.length,
filtered: (state) => {
if (state.filter === 'all') return state.items
return state.items.filter(...)
},
},
actions: {
addItem(text: string) {
this.items = [...this.items, text]
},
setFilter(f: 'all' | 'done' | 'pending') {
this.filter = f
},
},
})Setup API
Define a Store using the Setup function style, freely composing
Example
import { defineStore } from '@free-walk/svelte-store'
import { writable, derived } from 'svelte/store'
export const useCounterStore = defineStore('counter', () => {
const count = writable(0)
const double = derived(count, ($c) => $c * 2)
function increment() {
count.update((n) => n + 1)
}
function reset() {
count.set(0)
}
return { count, double, increment, reset }
}) In the Setup function return value, writable / readable / derived are recognized as state, plain functions are recognized as actions.
Store Instance
defineStore returns a function. Calling it returns a Store instance (singleton).
Instance Properties & Methods
| Property / Method | Type | Description |
|---|---|---|
$id | string | Store unique identifier |
$state | object | Current state snapshot (read-only) |
$patch(partial) | (partial: object) => void | Batch update state |
$reset() | () => void | Reset to initial state (Options API only) |
$subscribe(callback) | (cb) => unsubscribe | Listen for state changes |
subscribe(callback) | (cb) => unsubscribe | Svelte store protocol, supports $store syntax |
Example
const counter = useCounterStore()
// 批量更新
counter.$patch({ count: 10 })
// 重置
counter.$reset()
// 监听变化
const unsub = counter.$subscribe((state) => {
console.log('状态变化:', state)
})
// 在 Svelte 组件中使用 $ 自动订阅
// {$counter.count}Plugin System
Register global plugins via addPlugin, executed when each Store is created.
API
| Function | Param | Description |
|---|---|---|
addPlugin(plugin) | plugin: (context: PluginContext) => void | Register a global plugin |
PluginContext
| Property | Type | Description |
|---|---|---|
store | StoreInstance | Store instance |
id | string | Store ID |
Example: Persistence Plugin
import { addPlugin } from '@free-walk/svelte-store'
addPlugin(({ store, id }) => {
// 从 localStorage 恢复状态
const saved = localStorage.getItem('store-' + id)
if (saved) {
store.$patch(JSON.parse(saved))
}
// 监听变化并持久化
store.$subscribe((state) => {
localStorage.setItem('store-' + id, JSON.stringify(state))
})
})Helper Functions
| Function | Param | Description |
|---|---|---|
mapState(useStore, keys) | useStore: () => Store, keys: string[] | Extract state fields as independent Readable stores |
mapActions(useStore, keys) | useStore: () => Store, keys: string[] | Extract actions as independent functions |
getRegisteredStore(id) | id: string | Get a registered Store instance by ID |
clearStores() | — | Clear all registered Store instances |
mapState Example
import { mapState } from '@free-walk/svelte-store'
import { useCounterStore } from '../stores/counter'
const { count, filter } = mapState(useCounterStore, ['count', 'filter'])
// 在模板中
// {$count} {$filter} mapActions Example
import { mapActions } from '@free-walk/svelte-store'
import { useCounterStore } from '../stores/counter'
const { increment, reset } = mapActions(useCounterStore, ['increment', 'reset'])
// 直接调用
increment()
reset()Re-exports
For convenience, svelte-store re-exports the core APIs from svelte/store:
| Export | Source | Description |
|---|---|---|
writable | svelte/store | Writable store |
readable | svelte/store | Read-only store |
derived | svelte/store | Derived store |
get | svelte/store | Read store value once |
readonly | svelte/store | Wrap writable as read-only |
Example
// 可以直接从 svelte-store 导入,无需额外安装
import { writable, derived, get } from '@free-walk/svelte-store'
const count = writable(0)
const double = derived(count, ($c) => $c * 2)
console.log(get(count)) // 0