Guide · Open source
How to use valtio: proxy state for React and vanilla JS
Updated · written with AI from the project's own documentation and checked against our catalogue data
Valtio is a small state library for React and plain JavaScript that wraps your state object in a proxy, so you can change it directly. This guide shows you how to install it, create and mutate state, read it in React components, subscribe to changes outside components, and know when Valtio is a poor fit. By the end you should be able to set up a shared store and understand the snapshot and proxy split.
Quick start
- 1Install the package. Run npm install valtio in your project. Node.js is required.
- 2Create a proxy state. Import proxy from valtio and pass it an initial object.
- 3Mutate state directly. Assign to properties on the proxy from any code that holds a reference.
- 4Read state in a component. Call useSnapshot(state) in a component and render values from the returned snapshot.
- 5Subscribe outside React. Use subscribe, subscribeKey or watch to react to changes in plain JavaScript.
- 6Try the vanilla entry point. Import from valtio/vanilla when you need the same state outside React.
Install valtio with npm
Valtio is installed as a package with a package manager. The source lists Node.js as the prerequisite. Run the install command in your project folder.
- Prerequisite: Node.js
- Package manager: npm
npm install valtioWrap your state object in a proxy
Pass your state object to proxy(). Valtio turns that object into a self-aware proxy that tracks changes. Import proxy and useSnapshot from valtio.
import { proxy, useSnapshot } from 'valtio'
const state = proxy({ count: 0, text: 'hello' })Change state directly from anywhere
You change the proxy the same way you would change a normal JavaScript object. There is no reducer or action to write. Any code that has a reference to the state can update it.
setInterval(() => {
++state.count
}, 1000)Read state in React with useSnapshot
Call useSnapshot inside a component to get a local snapshot of the state. The README's rule of thumb is to read from snapshots in the render function and use the source proxy for writes. A component re-renders only when the parts of the state it accesses have changed, so the Counter below re-renders on count changes but not on text changes.
- Read values from snap in render.
- Write to the source proxy, such as state.count, in event handlers.
- The snapshot is read-only, so do not mutate snap.
function Counter() {
const snap = useSnapshot(state)
return (
<div>
{snap.count}
<button onClick={() => ++state.count}>+1</button>
</div>
)
}Subscribe to state outside components
You can read and subscribe to state without a component. subscribe() runs a callback on changes and returns a function that unsubscribes. You can also subscribe to a part of the state, or to a single primitive with subscribeKey from valtio/utils.
- subscribe(state, callback) watches the whole state.
- subscribe(state.obj, callback) watches only that portion.
- subscribeKey(state, 'count', callback) watches one primitive value.
- watch(get => ...) from valtio/utils auto-subscribes to the state it reads.
import { subscribe } from 'valtio'
const unsubscribe = subscribe(state, () =>
console.log('state has changed to', state),
)
unsubscribe()Use valtio without React
Valtio also has a vanilla entry point. Import from valtio/vanilla to use proxy, subscribe and snapshot in plain JavaScript. A snapshot is an immutable object, so take one when you need a stable copy of the state.
The source also describes useProxy from valtio/utils, which gives a shallow proxy that can be mutated at the root level. It is meant to reduce the confusion of the proxy and snapshot split for beginners.
- Use valtio/vanilla for non-React code.
- Use useProxy from valtio/utils if you find the proxy and snapshot split confusing; it only supports root-level mutation.
import { proxy, subscribe, snapshot } from 'valtio/vanilla'
const state = proxy({ count: 0, text: 'hello' })
subscribe(state, () => {
const obj = snapshot(state)
})Avoid common pitfalls
Valtio's README covers a few traps. Using this inside proxied methods can fail, because this points to the snapshot in render and snapshots are frozen. The README recommends arrow functions instead. For input fields, state mutations are batched by default, so the README shows useSnapshot with sync: true to disable batching. Large objects you do not want proxied can be stored with ref().
For TypeScript, the snapshot type is deeply read-only and can be too strict. The README shows a module declaration that loosens the useSnapshot type. If you are new to Valtio, the README recommends eslint-plugin-valtio.
- Prefer arrow functions over this in proxied state.
- Use useSnapshot(state, { sync: true }) for input fields.
- Use ref() to keep large or accessor-heavy objects out of tracking.
- Consider eslint-plugin-valtio if you are new to the library.
const state = proxy({
count: 0,
inc: () => {
++state.count
},
})What people use it for
- A React app with shared counters or form text that several components read without a reducer.
- Plain JavaScript code that subscribes to a state object and logs or syncs changes.
- A React 19 component that reads async data with the use hook inside Suspense.
- Holding a DOM node or other large object in state with ref() so it is not tracked.
Frequently asked questions
How do I install valtio?
Run npm install valtio in your project. The source lists Node.js as the prerequisite and npm as the install method.
Is valtio free to use?
Valtio is released under the MIT licence, according to the project information. Check the LICENSE file in the repository for the full terms.
Does valtio work without React?
Yes. The README says Valtio is not tied to React and shows usage from valtio/vanilla with proxy, subscribe and snapshot.
Why does my component re-render when I change state?
A component re-renders only when the parts of the state it reads through the snapshot have changed. Read only the values you need from snap inside the render function.
Why doesn't this work with useTransition in valtio?
The README says the Suspense pattern with use still suffers from de-opt issues that prevent useTransition from working well. It mentions the third-party library use-valtio as a mitigation.
How does valtio compare to Zustand, Jotai, Redux Toolkit and MobX?
The project information lists these as comparable projects. Valtio is distinct for direct mutation of a proxy and snapshots, while Redux Toolkit and Zustand are often used with reducers or store actions. Compare them against your team's preferred state style before choosing.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
Valtio suits React developers who want shared state with little boilerplate and who are comfortable with direct mutation and snapshots. Pick something else if you want strictly immutable, reducer-based state, if you are not ready to learn proxies, or if you depend on Suspense with useTransition working smoothly.
Install options & downloads