All skills
skilld-dev avatar

/tanstack-vue-store-skilld

@b9c39cb

Vue adapter for TanStack Store, a framework agnostic type-safe store. ALWAYS use when writing code importing "@tanstack/vue-store" in a Vue app. Covers the useSelector, useAtom, useStore (deprecated), and _useStore hooks, the re-exported @tanstack/store core API (createStore, createAtom, createAsyncAtom, batch, flush, shallow), debugging, best practices, and migration between @tanstack/vue-store versions.

Use this Skill: https://skilld.dev/gh/skilld-dev/vue-ecosystem-skills/tanstack-vue-store-skilld

This session only. Nothing lands on disk.

referencespatterns.md

≈930 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Patterns and recipes

Working examples for common @tanstack/vue-store tasks in Vue 3 <script setup>. Store creation APIs come from the core re-export (src/index.ts:1).

Shared store in a plain module

The documented sharing pattern: instantiate outside components, import anywhere (Vue quick start).

// store.ts
import { createStore } from '@tanstack/vue-store'

export const store = createStore({ dogs: 0, cats: 0 })

export function updateState(animal: 'dogs' | 'cats') {
  store.setState((state) => ({ ...state, [animal]: state[animal] + 1 }))
}
<!-- Display.vue -->
<script setup>
import { useSelector } from '@tanstack/vue-store'
import { store } from './store'

const props = defineProps({ animal: String })
const count = useSelector(store, (state) => state[props.animal])
</script>

<!-- Re-renders only when state[props.animal] changes -->
<template>
  <div>{{ animal }}: {{ count }}</div>
</template>

Read and write one atom

<script setup>
import { createAtom, useAtom } from '@tanstack/vue-store'

const countAtom = createAtom(0) // module scope in real code
const [count, setCount] = useAtom(countAtom)
</script>

<template>
  <button @click="setCount((prev) => prev + 1)">{{ count }}</button>
</template>

Actions factory with _useStore

import { createStore } from '@tanstack/vue-store'

export const petStore = createStore({ cats: 0 }, ({ setState }) => ({
  addCat: () => setState((s) => ({ ...s, cats: s.cats + 1 })),
  reset: () => setState({ cats: 0 }),
}))
<script setup>
import { _useStore } from '@tanstack/vue-store'
import { petStore } from './store'

const [cats, { addCat, reset }] = _useStore(petStore, (s) => s.cats)
</script>

Derived state

import { createStore, useSelector } from '@tanstack/vue-store'

const counter = createStore(0)
const doubled = createStore(() => counter.state * 2)          // ReadonlyStore
const history = createStore<Array<number>>([], (prev = []) => [...prev, counter.state]) // prev accumulates

// In a component
const d = useSelector(doubled)

Async data with createAsyncAtom

<script setup>
import { createAsyncAtom, useSelector } from '@tanstack/vue-store'

const userAtom = createAsyncAtom(() => fetchUser()) // module scope in real code
const user = useSelector(userAtom)
</script>

<template>
  <p v-if="user.status === 'pending'">Loading…</p>
  <p v-else-if="user.status === 'error'">{{ user.error }}</p>
  <UserProfile v-else-if="user.status === 'done'" :user="user.data" />
</template>

Batched updates

import { batch } from '@tanstack/vue-store'

batch(() => {
  counter.setState((n) => n + 1)
  otherStore.setState((s) => ({ ...s, updated: true }))
})
// Subscribers notified once, with final state

Subscribing outside components

import { createStore } from '@tanstack/vue-store'

const store = createStore({ count: 0 })
const { unsubscribe } = store.subscribe((state) => console.log(state.count))

Choosing a compare function

Selector returns Compare to pass
Primitive, or a stable reference from state none; default === is correct
Fresh object or array { compare: shallow }
Date shallow compares timestamps; write a custom compare for other semantics
Deeply nested new objects custom recursive compare, or select a narrower slice
import { shallow, useSelector } from '@tanstack/vue-store'

const bad = useSelector(store, (s) => ({ a: s.a, b: s.b }))                    // updates every notification
const good = useSelector(store, (s) => ({ a: s.a, b: s.b }), { compare: shallow })

Source: SKILL.md on GitHub

No alerts8d3 checks · Risk SAFE
  • Gen Agent Trust Hub8d

    This skill is a documentation and reference guide for the @tanstack/vue-store library. It contains API definitions, best practices, release notes, and issue summaries. No security risks or malicious patterns were identified.

  • Socket8d

    No alerts

  • Snyk8d

    Risk: LOW · No issues

Signed by skilld at b9c39cb. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Activeupdated last week

README badge

README badge for skilld-dev/vue-ecosystem-skills/tanstack-vue-store-skilld