Valtio: The Proxy-Based Secret to Effortless React State Management
Ditch the boilerplate and embrace reactivity with Valtio — a minimalist state management solution for modern React apps.
Valtio: The Proxy-Based Secret to Effortless React State Management
Introduction
State management in React has come a long way — from prop drilling to Context API, Redux, MobX, and beyond. While these solutions offer powerful tools for managing state, they often come with trade-offs in complexity, boilerplate, or performance.
Enter Valtio: a proxy-based state management library for React that brings simplicity and reactivity together. If you’re looking for a lightweight alternative that feels almost magical in its approach, Valtio might just be your new favorite tool.
In this post, we’ll dive into:
- What Valtio is and how it works
- How it compares to other state management tools
- Core concepts and real-world usage examples
- Best practices and gotchas
What is Valtio?
Valtio is a state management library developed by the creators of Jotai, with a focus on using JavaScript proxies to wrap your state in a reactive shell. It’s designed to feel native to JavaScript — no need for dispatchers, actions, or reducers.
Here’s a taste of what Valtio looks like:
import { proxy, useSnapshot } from 'valtio'
const state = proxy({ count: 0 })
function Counter() {
const snap = useSnapshot(state)
return (
<>
<p>Count: {snap.count}</p>
<button onClick={() => state.count++}>Increment</button>
</>
)
}
Yes, it’s really that simple.
Why Choose Valtio?
Here’s what makes Valtio a standout option:
- ✅ Zero Boilerplate: No actions, no reducers, no dispatchers.
- ✅ Built on Proxies: Native JavaScript support with automatic tracking.
- ✅ Fine-Grained Reactivity: Only the parts of the UI that depend on state will re-render.
- ✅ Supports Complex Structures: Nested objects, arrays, maps, and sets.
- ✅ First-Class Support for React Suspense and Concurrent Mode.
How Valtio Works Under the Hood
Valtio uses the Proxy object introduced in ES6 to track and intercept changes made to the state. When you wrap an object using proxy(), Valtio becomes aware of what properties are accessed or modified.
The useSnapshot() hook then provides a read-only snapshot of the current state, triggering React re-renders only when the accessed parts change.
const state = proxy({ user: { name: 'Hazrat' }, online: true })
const Component = () => {
const snap = useSnapshot(state)
return <div>{snap.user.name}</div> // only re-renders if user.name changes
}
This makes it highly efficient, especially in large-scale apps with deeply nested state trees.
Getting Started with Valtio
Installation
npm install valtio
or
yarn add valtio
Basic Usage
// state.js
import { proxy } from 'valtio'
export const state = proxy({
count: 0,
text: 'Hello World',
})
// Counter.js
import React from 'react'
import { useSnapshot } from 'valtio'
import { state } from './state'
function Counter() {
const snap = useSnapshot(state)
return (
<>
<p>{snap.text}: {snap.count}</p>
<button onClick={() => state.count++}>Add</button>
</>
)
}
No context providers, no reducers, and no boilerplate — just straightforward reactivity.
Advanced Usage
Nested Objects
Valtio handles nested state effortlessly:
const state = proxy({
user: {
name: 'Alice',
address: {
city: 'New York'
}
}
})
const snap = useSnapshot(state)
console.log(snap.user.address.city) // Reactive access
Arrays, Maps, Sets
const state = proxy({
todos: [
{ id: 1, text: 'Learn Valtio', completed: false },
{ id: 2, text: 'Build something cool', completed: false }
]
})
Mutating arrays (e.g., push, splice, etc.) works as expected and triggers re-renders.
Derived State
Valtio supports computed values using subscribe or external derivation:
import { derive } from 'valtio/utils'
const state = proxy({ count: 5 })
const derived = derive({
double: get => get(state).count * 2,
})
This separation keeps your UI logic clean and declarative.
Integration with Async & Suspense
Valtio plays nicely with Suspense and async data:
const state = proxy({
user: fetchUserData(), // returns a promise
})
function Profile() {
const snap = useSnapshot(state)
return <div>{snap.user.name}</div>
}
With help from valtio/utils, you can even use suspense-ready patterns that wait for promises to resolve before rendering.
Valtio vs. Redux / Zustand / Jotai

Valtio is perfect for small to medium-sized apps and when you want simplicity without giving up control.
When to Use Valtio
✅ Ideal for:
- Prototypes and MVPs
- Apps with dynamic or nested state
- Developers who prefer minimalism and native JS syntax
🚫 Not ideal for:
- Large-scale enterprise apps with strict architecture
- Teams already invested heavily in Redux or similar ecosystems
- Needing time-travel debugging or full-blown devtools
Common Pitfalls & Gotchas
- Don’t mutate the snapshot — it’s read-only:
snap.count++ // ❌ will throw error
state.count++ // ✅ do this
2. Avoid using snap outside components — the proxy is for reactivity within render cycles.
3. Nested reactivity — while proxies support deep nesting, excessive nesting can still lead to complexity. Refactor wisely.
Best Practices
- Use separate state files to keep logic organized.
- Combine with Zustand or Jotai for hybrid state approaches if needed.
- Pair with TypeScript for maximum type safety.
- Memoize derived state if it becomes performance-critical.
- Write custom hooks to abstract logic from UI components.
Real-World Use Case: Todo App Example
// store.js
import { proxy } from 'valtio'
export const todoState = proxy({
todos: [],
newTodo: '',
})
// Add helper methods (optional)
export const addTodo = () => {
if (todoState.newTodo.trim()) {
todoState.todos.push({ text: todoState.newTodo, done: false })
todoState.newTodo = ''
}
}
// TodoApp.js
import { useSnapshot } from 'valtio'
import { todoState, addTodo } from './store'
function TodoApp() {
const snap = useSnapshot(todoState)
return (
<div>
<input
value={snap.newTodo}
onChange={e => (todoState.newTodo = e.target.value)}
/>
<button onClick={addTodo}>Add</button>
<ul>
{snap.todos.map((todo, idx) => (
<li key={idx}>
<input
type="checkbox"
checked={todo.done}
onChange={() => (todo.done = !todo.done)}
/>
{todo.text}
</li>
))}
</ul>
</div>
)
}
A fully reactive Todo app in under 50 lines!
Final Thoughts
Valtio represents a breath of fresh air in the often convoluted world of state management. Its proxy-based approach feels natural, intuitive, and performant — allowing you to think in plain JavaScript without sacrificing reactivity or scalability.
Whether you’re building a side project or exploring alternatives to Redux, Valtio offers a fantastic developer experience with minimal friction.
Have you tried Valtio in your projects? Share your experience in the comments below.
Thank you for being a part of the community
Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: **X | [LinkedIn](https://www.linkedin.com/company/inplainenglish/) | [YouTube](https://www.youtube.com/@InPlainEnglish) | [Newsletter](https://newsletter.plainenglish.io/) | [Podcast](https://open.spotify.com/show/7qxylRWKhvZwMz2WuEoua0) | [Differ](https://differ.blog/inplainenglish) | [Twitch](https://twitch.tv/inplainenglish)**
- **Check out CoFeed, the smart way to stay up-to-date with the latest in tech 🧪**
- **Start your own free AI-powered blog on Differ** 🚀
- **Join our content creators community on Discord** 🧑🏻💻
- For more content, visit **plainenglish.io + [stackademic.com](https://stackademic.com/)**
메타데이터
- post_id
- b4ea64bbef09
- slug
- valtio-the-proxy-based-secret-to-effortless-react-state-management-b4ea64bbef09
- url
- https://javascript.plainenglish.io/valtio-the-proxy-based-secret-to-effortless-react-state-management-b4ea64bbef09
- canonical_url
- https://javascript.plainenglish.io/valtio-the-proxy-based-secret-to-effortless-react-state-management-b4ea64bbef09
- author_url
- https://medium.com/@codebyumar
- status
- ok
- fetched_at
- 2026-07-20 07:40:56