@nexus-state/vue
v0.1.7
Published
> Vue integration for Nexus State — fine-grained reactivity with Vue composables > > [](https://www.npmjs.com/package/@nexus-state/vue) > [
<script setup>
import { atom, createStore } from '@nexus-state/core';
import { useAtom } from '@nexus-state/vue';
// Create atom and store
const countAtom = atom(0, 'count');
const store = createStore();
// useAtom returns a Ref (auto-unpacks in template)
const [count, setCount] = useAtom(countAtom, store);
</script>
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="setCount(c => c + 1)">+</button>
</div>
</template>Minimum required: Vue 3.0.0
🎯 Why Nexus State for Vue?
Comparison with Native Solutions
| Feature | Nexus State | Pinia | Vuex | |---------|-------------|-------|------| | Fine-grained updates | ✅ Per-atom | ⚠️ Store-level | ❌ Store-wide | | No setup boilerplate | ✅ Direct atom usage | ⚠️ Store definition | ❌ Actions/mutations | | Multi-framework | ✅ React/Vue/Svelte | ❌ Vue-only | ❌ Vue-only | | DevTools | ✅ Redux DevTools | ✅ Vue Devtools | ✅ Vue Devtools | | Bundle size | 1.5KB | 9KB | 15KB |
✅ Choose Nexus State if you need:
- Fine-grained reactivity (per-atom updates)
- No store definition boilerplate
- Multi-framework state sharing
- Isolated stores (SSR, testing)
❌ Use alternatives if:
- Vue-only project → Pinia (better Vue integration)
- Legacy Vuex codebase → Vuex (migration path)
- Simple global state → Vue
reactive()(built-in)
📖 Core Composables
useAtom(atom, store?)
Read + write access to an atom. Returns [Ref, Setter].
<script setup>
import { useAtom } from '@nexus-state/vue';
const [count, setCount] = useAtom(countAtom, store);
</script>
<template>
<div>
<p>{{ count }}</p>
<button @click="setCount(c => c + 1)">+</button>
</div>
</template>useAtomValue(atom, store?)
Read-only access. Returns Ref (auto-unpacks in template).
<script setup>
import { useAtomValue } from '@nexus-state/vue';
const count = useAtomValue(countAtom, store);
// count is a Ref<number>
</script>
<template>
<p>Count: {{ count }}</p>
</template>useSetAtom(atom, store?)
Write-only access. Returns setter function.
<script setup>
import { useSetAtom } from '@nexus-state/vue';
const setCount = useSetAtom(countAtom, store);
// Component won't re-render from atom changes
</script>
<template>
<button @click="setCount(c => c + 1)">+</button>
</template>Vue Reactivity Integration
<script setup>
import { ref, computed } from 'vue';
import { atom } from '@nexus-state/core';
import { useAtomValue } from '@nexus-state/vue';
// Atoms work with Vue reactivity
const countAtom = atom(0);
const doubleAtom = atom((get) => get(countAtom) * 2);
// Returns Ref<number>
const count = useAtomValue(countAtom);
// Returns ComputedRef<number>
const double = useAtomValue(doubleAtom);
// Can use with Vue's ref
const localRef = ref(0);
</script>
<template>
<div>
<p>{{ count }} × 2 = {{ double }}</p>
<p>Local: {{ localRef }}</p>
</div>
</template>Multiple Stores
<script setup>
import { atom, createStore } from '@nexus-state/core';
import { useAtom } from '@nexus-state/vue';
const store1 = createStore();
const store2 = createStore();
const value1 = useAtom(atom1, store1);
const value2 = useAtom(atom2, store2);
</script>
<template>
<div>
<p>Store 1: {{ value1 }}</p>
<p>Store 2: {{ value2 }}</p>
</div>
</template>SSR with Isolated Stores
<script setup>
import { atom, createStore } from '@nexus-state/core';
import { useAtom } from '@nexus-state/vue';
const props = defineProps({ initialState: Object });
// Create isolated store per request
const store = createStore();
if (props.initialState) {
store.setState(props.initialState);
}
const user = useAtom(userAtom, store);
</script>
<template>
<div>{{ user?.name }}</div>
</template>🔌 Integration with Ecosystem
Data Fetching (@nexus-state/query)
<script setup>
import { useQuery } from '@nexus-state/query/vue';
import { useAtomValue } from '@nexus-state/vue';
const userId = useAtomValue(userIdAtom, store);
const { data: user, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: fetchUser,
});
</script>
<template>
<div v-if="isLoading">Loading...</div>
<div v-else>{{ user.name }}</div>
</template>📖 Full docs: npm
Persistence (@nexus-state/persist)
<script setup>
import { persistAtom } from '@nexus-state/persist';
import { useAtomValue } from '@nexus-state/vue';
// Persist atom to localStorage
const settingsAtom = persistAtom(
{ theme: 'light' },
'settings',
{ storage: 'localStorage' }
);
const settings = useAtomValue(settingsAtom, store);
</script>
<template>
<div>Theme: {{ settings.theme }}</div>
</template>📖 Full docs: npm
📚 API Reference
| Composable | Signature | Description |
|------------|-----------|-------------|
| useAtom | useAtom(atom, store?) | Read + write (returns [Ref, Setter]) |
| useAtomValue | useAtomValue(atom, store?) | Read only (returns Ref) |
| useSetAtom | useSetAtom(atom, store?) | Write only (returns function) |
🔧 Troubleshooting
1. "useAtom requires a store" error
Cause: Store not provided.
Solution:
<script setup>
// Option 1: Provide store explicitly
const [count] = useAtom(countAtom, store);
</script>2. Ref not updating in template
Cause: Using useSetAtom (by design — no subscription).
Solution: Use useAtom or useAtomValue for read access.
<script setup>
// ❌ Won't update
const setCount = useSetAtom(countAtom);
// ✅ Will update
const [count, setCount] = useAtom(countAtom, store);
</script>3. SSR hydration mismatch
Cause: Server and client have different initial state.
Solution: Use setState() to hydrate on client.
<script setup>
const props = defineProps({ initialState: Object });
const store = createStore();
// Hydrate on mount
onMounted(() => {
if (props.initialState) {
store.setState(props.initialState);
}
});
</script>📦 Related Packages
| Package | Description | npm | |---------|-------------|-----| | @nexus-state/core | Core concepts (atoms, stores) | Install | | @nexus-state/react | React integration | Install | | @nexus-state/svelte | Svelte integration | Install | | @nexus-state/query | Data fetching | Install | | @nexus-state/async | Simple async state | Install | | @nexus-state/persist | LocalStorage persistence | Install |
🔗 See Also
- Core: @nexus-state/core — Atoms, stores, subscriptions
- Data fetching: @nexus-state/query — SSR prefetch, caching
- Async: @nexus-state/async — Simple loading states
- Persistence: @nexus-state/persist — LocalStorage
- Forms: @nexus-state/form — Schema-based forms
- DevTools: @nexus-state/devtools — Debugging
Full ecosystem: Nexus State Packages
📄 License
MIT
