# valtio
**Repository Path**: mirrors_fkhadra/valtio
## Basic Information
- **Project Name**: valtio
- **Description**: 💊 Valtio makes proxy-state simple for React and Vanilla
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-01-11
- **Last Updated**: 2026-10-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
npm i valtio makes proxy-state simple
[](https://github.com/pmndrs/valtio/actions?query=workflow%3ALint)
[](https://bundlephobia.com/result?p=valtio)
[](https://www.npmjs.com/package/valtio)
[](https://www.npmjs.com/package/valtio)
[](https://discord.gg/poimandres)
#### Wrap your state object
Valtio turns the object you pass it into a self-aware proxy.
```jsx
import { proxy, useSnapshot } from 'valtio'
const state = proxy({ count: 0, text: 'hello' })
```
#### Mutate from anywhere
You can make changes to it in the same way you would to a normal js-object.
```jsx
setInterval(() => {
++state.count
}, 1000)
```
#### React via useSnapshot
Create a local snapshot that catches changes. Rule of thumb: read from snapshots, mutate the source. The component will only re-render when the parts of the state you access have changed, it is render-optimized.
```jsx
// This will re-render on `state.count` change but not on `state.text` change
function Counter() {
const snap = useSnapshot(state)
return (
{snap.count}
)
}
```
Note: useSnapshot returns a new proxy for render optimization.
Internally, `useSnapshot` calls `snapshot` in valtio/vanilla,
and wraps the snapshot object with another proxy to detect property access.
This feature is based on [proxy-compare](https://github.com/dai-shi/proxy-compare).
Two kinds of proxies are used for different purposes:
- `proxy()` from `valtio/vanilla` is for mutation tracking or write tracking.
- `createProxy()` from `proxy-compare` is for usage tracking or read tracking.
Use of `this` is for expert users.
Valtio tries best to handle `this` behavior
but it's hard to understand without familiarity.
```js
const state = proxy({ count: 0, inc() { ++this.count } })
state.inc() // `this` points to `state` and it works fine
const snap = useSnapshot(state)
snap.inc() // `this` points to `snap` and it doesn't work because snapshot is frozen
```
To avoid this pitfall, the recommended pattern is not to use `this` and prefer arrow function.
```js
const state = proxy({ count: 0, inc: () => { ++state.count } })
```
If you are new to this, it's highly recommended to use
[eslint-plugin-valtio](https://github.com/pmndrs/eslint-plugin-valtio).
#### Subscribe from anywhere
You can access state outside of your components and subscribe to changes.
```jsx
import { subscribe } from 'valtio'
// Suscribe to all state changes
const unsubscribe = subscribe(state, () => console.log('state has changed to', state))
// Unsubscribe by calling the result
unsubscribe()
```
You can also subscribe to a portion of state.
```jsx
const state = proxy({ obj: { foo: 'bar' }, arr: ['hello'] })
subscribe(state.obj, () => console.log('state.obj has changed to', state.obj))
state.obj.foo = 'baz'
subscribe(state.arr, () => console.log('state.arr has changed to', state.arr))
state.arr.push('world')
```
To subscribe to a primitive value of state, consider `subscribeKey` in utils.
```jsx
import { subscribeKey } from 'valtio/utils'
const state = proxy({ count: 0, text: 'hello' })
subscribeKey(state, 'count', (v) => console.log('state.count has changed to', v))
```
There is another util `watch` which might be convenient in some cases.
```jsx
import { watch } from 'valtio/utils'
const state = proxy({ count: 0 })
const stop = watch((get) => {
console.log('state has changed to', get(state)) // auto-subscribe on use
})
```
#### Suspend your components
Valtio supports React-suspense and will throw promises that you access within a components render function. This eliminates all the async back-and-forth, you can access your data directly while the parent is responsible for fallback state and error handling.
```jsx
const state = proxy({ post: fetch(url).then((res) => res.json()) })
function Post() {
const snap = useSnapshot(state)
return
{snap.post.title}
}
function App() {
return (
waiting...}>
)
}
```
#### Holding objects in state without tracking them
This may be useful if you have large, nested objects with accessors that you don't want to proxy. `ref` allows you to keep these objects inside the state model.
See [#61](https://github.com/pmndrs/valtio/issues/61) and [#178](https://github.com/pmndrs/valtio/issues/178) for more information.
```js
import { proxy, ref } from 'valtio'
const state = proxy({
count: 0,
dom: ref(document.body),
})
```
#### Update transiently (for often occuring state-changes)
You can read state in a component without causing re-render.
```jsx
function Foo() {
const { count, text } = state
// ...
```
Or, you can have more control with subscribing in useEffect.
```jsx
function Foo() {
const total = useRef(0)
useEffect(() => subscribe(state.arr, () => {
total.current = state.arr.reduce((p, c) => p + c)
}), [state.obj])
// ...
```
#### Update synchronously
By default, state mutations are batched before triggering re-render.
Sometimes, we want to disable the batching.
The known use case of this is `` [#270](https://github.com/pmndrs/valtio/issues/270).
```jsx
function TextBox() {
const snap = useSnapshot(state, { sync: true })
return (state.text = e.target.value)} />
}
```
#### Dev tools
You can use [Redux DevTools Extension](https://github.com/zalmoxisus/redux-devtools-extension) for plain objects and arrays.
```jsx
import { devtools } from 'valtio/utils'
const state = proxy({ count: 0, text: 'hello' })
const unsub = devtools(state, 'state name')
```
Manipulating state with Redux DevTools
The screenshot below shows how to use Redux DevTools to manipulate state. First select the object from the instances drop down. Then type in a JSON object to dispatch. Then click "Dispatch". Notice how it changes the state.
#### Use it vanilla
Valtio is not tied to React, you can use it in vanilla-js.
```jsx
import { proxy, subscribe, snapshot } from 'valtio/vanilla'
const state = proxy({ count: 0, text: 'hello' })
subscribe(state, () => {
console.log('state is mutated')
const obj = snapshot(state) // A snapshot is an immutable object
})
```
#### `useProxy` macro
We have a convenient macro with
[babel-plugin-macros](https://www.npmjs.com/package/babel-plugin-macros).
```js
import { useProxy } from 'valtio/macro'
const Component = () => {
useProxy(state)
return (
{state.count}
)
}
// the code above becomes the code below.
import { useSnapshot } from 'valtio'
const Component = () => {
const snap = useSnapshot(state)
return (
{snap.count}
)
}
```
#### `derive` util
You can subscribe to some proxies and create a derived proxy.
```js
import { derive } from 'valtio/utils'
// create a base proxy
const state = proxy({
count: 1,
})
// create a derived proxy
const derived = derive({
doubled: (get) => get(state).count * 2,
})
// alternatively, attach derived properties to an existing proxy
derive({
tripled: (get) => get(state).count * 3,
}, {
proxy: state,
})
```
#### `proxyWithComputed` util
You can have computed values with dependency tracking with property access.
Dependency tracking in `proxyWithComputed` conflicts with the work in `useSnapshot`.
React users should prefer using `derive`.
`proxyWithComputed` works well for some edge cases and for vanilla-js users.
```js
import { proxyWithComputed } from 'valtio/utils'
const state = proxyWithComputed({
count: 1,
}, {
doubled: snap => snap.count * 2
})
// Computed values accept custom setters too:
const state2 = proxyWithComputed({
firstName: 'Alec',
lastName: 'Baldwin'
}, {
fullName: {
get: (snap) => snap.firstName + ' ' + snap.lastName,
set: (state, newValue) => { [state.firstName, state.lastName] = newValue.split(' ') },
}
})
// if you want a computed value to derive from another computed, you must declare the dependency first:
const state = proxyWithComputed({
count: 1,
}, {
doubled: snap => snap.count * 2,
quadrupled: snap => snap.doubled * 2
})
```
The last use case fails to infer types in TypeScript
[#192](https://github.com/pmndrs/valtio/issues/192).
#### `proxyWithHistory` util
This is a utility function to create a proxy with snapshot history.
```js
import { proxyWithHistory } from 'valtio/utils'
const state = proxyWithHistory({ count: 0 })
console.log(state.value) // ---> { count: 0 }
state.value.count += 1
console.log(state.value) // ---> { count: 1 }
state.undo()
console.log(state.value) // ---> { count: 0 }
state.redo()
console.log(state.value) // ---> { count: 1 }
```
#### Plugins
- [eslint-plugin-valtio](https://github.com/pmndrs/eslint-plugin-valtio)
#### Recipes
Valtio is unopinionated about best practices.
The community is working on recipes on wiki pages.
- [How to organize actions](https://github.com/pmndrs/valtio/wiki/How-to-organize-actions)
- [How to persist states](https://github.com/pmndrs/valtio/wiki/How-to-persist-states)
- [How to use with context](https://github.com/pmndrs/valtio/wiki/How-to-use-with-context)
- [How to split and compose states](https://github.com/pmndrs/valtio/wiki/How-to-split-and-compose-states)