Installations
npm install proxy-state-tree
Developer Guide
Typescript
Yes
Module System
CommonJS
Node Version
10.24.1
NPM Version
6.3.0
Score
91.9
Supply Chain
100
Quality
90
Maintenance
100
Vulnerability
100
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (100%)
validate.email 🚀
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Developer
christianalfoni
Download Statistics
Total Downloads
2,662,493
Last Day
1,848
Last Week
10,527
Last Month
46,973
Last Year
380,180
GitHub Statistics
MIT License
68 Stars
37 Commits
3 Watchers
1 Branches
3 Contributors
Updated on Jan 24, 2025
Bundle Size
10.13 kB
Minified
3.02 kB
Minified + Gzipped
Package Meta Information
Latest Version
6.3.0
Package Id
proxy-state-tree@6.3.0
Unpacked Size
180.95 kB
Size
35.01 kB
File Count
34
NPM Version
6.3.0
Node Version
10.24.1
Total Downloads
Cumulative downloads
Total Downloads
2,662,493
Last Day
-8.1%
1,848
Compared to previous day
Last Week
-7.6%
10,527
Compared to previous week
Last Month
13.5%
46,973
Compared to previous month
Last Year
6.4%
380,180
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dev Dependencies
3
proxy-state-tree
An implementation of the Mobx/Vue state tracking approach, for library authors
DEPRECATED
Has moved to repo: https://github.com/cerebral/overmind
npm install proxy-state-tree@beta
Why
The proxy-state-tree project is created to stimulate innovation in state management. The introduction of Flux was followed by a big wave of libraries trying to improve on the idea. All these iterations helped moving the community forward and Redux was born a year later. It was frustrating to have all these variations of the same idea, but at the same time it made the core idea better. One factor I believe made this possible is that Flux state management is based on immutability. It is a difficult concept to understand, but when you understand it, it is easy to implement the concept of change. You literally just check if a value you depend on has changed. That said, immutability tends to put a lof effort on the hands of the consumer. You have to think really hard about how you structure state and expose state to components to avoid performance issues and prevent boilerplate.
vuejs and mobx has a different approach to change. They use getter/setter interception to track access to state and changes to state. This concept completely removes the consumers burden of how the state is structured and how it is exposed to the different parts of the app. You just expose state in any form and the usage is automatically tracked and optimized. The problem with this approach though is that it is difficult to implement as a library author. I want to change that!
proxy-state-tree is a low level implementation of the getter/setter interception with a single state tree to help library authors innovate. I hope to see innovations that removes the burden that immutability currently causes, but keeps the guarantees that was introduced in Flux. I invite you to make a mobx and redux baby! ;-)
Examples
-
Vue example with a simple implementation that allows you to define a state tree and expose a store to the components which can be mutated in the methods
-
Preact example with a simple implementation of a external state and actions passed on a Provider. Also includes a simple, but inspiring debugger
Create a tree
1import ProxyStateTree from 'proxy-state-tree' 2 3const tree = new ProxyStateTree({}) 4 5console.log(tree.get()) // {}
As a library author you would typically expose a mechanism to define the initial state of the application, which you would pass to the ProxyStateTree. You would also expose a way to access the state, hiding the tree.get()
from the consumer of your library.
Track access
You can track access to the state by using the startPathsTracking and clearPathsTracking methods.
1import ProxyStateTree from 'proxy-state-tree' 2 3const tree = new ProxyStateTree({ 4 foo: 'bar', 5 bar: 'baz' 6}) 7const state = tree.get() 8 9const trackId = tree.startPathsTracking() 10const foo = state.foo 11const bar = state.bar 12const paths = tree.clearPathsTracking(trackId) 13 14console.log(paths) // Set { 'foo', 'bar' }
You would typically use this mechanism to track usage of state. For example rendering a component, calculating a a computed value etc. The returned paths array is stored for later usage. The paths structure is used internally by proxy-state-tree, but you can also consume it as a library author to for example showing components and what paths they depend on in a devtool. Nested paths uses dot notation, for example ['foo.bar']
. Path tracking can be nested, but they can not run at the same time. Meaning the nested tracking must finish before the outer tracker.
Track mutations
1import ProxyStateTree from 'proxy-state-tree' 2 3const tree = new ProxyStateTree({ 4 foo: 'bar', 5 bar: [] 6}) 7const state = tree.get() 8 9tree.startMutationTracking() 10state.foo = 'bar2' 11state.bar.push('baz') 12const mutations = tree.clearMutationTracking() 13 14console.log(mutations) 15/* 16 [{ 17 method: 'set', 18 path: ['foo'], 19 args: ['bar2'] 20 }, { 21 method: 'push', 22 path: ['bar'], 23 args: ['baz'] 24 }] 25*/
You would use startMutationTracking and clearMutationTracking around logic that is allowed to do mutations, for example actions or similar. Trying to mutate without this tracking active results in an error. The returned array can be used in combination with a devtool.
Check need to update
1import ProxyStateTree from 'proxy-state-tree' 2 3const tree = new ProxyStateTree({ 4 foo: 'bar', 5 bar: 'baz' 6}) 7const state = tree.get() 8 9function render () { 10 const trackId = tree.startPathsTracking() 11 const foo = state.foo 12 const bar = state.bar 13 14 return tree.clearPathsTracking(trackId) 15} 16 17const listener = tree.addMutationListener(render(), () => { 18 // Runs when mutations matches paths passed in 19 20 // Whenever mutations affecting these paths occurs 21 // we typically create the paths again due to possible 22 // conditional logic, in "render" in this example 23 listener.update(render()) 24}) 25 26tree.startMutationTracking() 27state.foo = 'bar2' 28state.bar.push('baz') 29tree.clearMutationTracking() 30 31// This command flushes out the current mutations and 32// notifies any listeners 33tree.flush() 34 35// Remove listener 36listener.dispose()
Here we combine the tracked paths with the mutations performed to see if this components, computed or whatever indeed needs to run again, doing a new startPathsTracking and clearPathsTracking.
Dynamic state values
If you insert a function into the state tree it will be called when accessed. The function is passed the proxy-state-tree instance and the path of where the function lives in the tree.
1import ProxyStateTree from 'proxy-state-tree' 2 3const tree = new ProxyStateTree({ 4 foo: (proxyStateTree, path) => {} 5})
The allows you to easily extend functionality with for example a computed concept that lives in the tree, as you can see in this codesandbox.

No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 4/20 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 15 are checked with a SAST tool
Reason
65 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-6chw-6frg-f759
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx
- Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-c6rq-rjc2-86v2
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2
- Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3
- Warn: Project is vulnerable to: MAL-2023-462
- Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6
- Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9
- Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f
- Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p
- Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv
- Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8
- Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65
- Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh
- Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44
- Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988
- Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj
- Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37
- Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546
- Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp
- Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574
- Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm
- Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9
- Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm
- Warn: Project is vulnerable to: GHSA-4xcv-9jjx-gfj3
- Warn: Project is vulnerable to: GHSA-f9cm-qmx5-m98h
- Warn: Project is vulnerable to: GHSA-7wpw-2hjm-89gp
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-fhjf-83wg-r2j9
- Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp
- Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr
- Warn: Project is vulnerable to: GHSA-j44m-qm6p-hp7m
- Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9
- Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw
- Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc
- Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh
- Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p
- Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
- Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh
- Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp
Score
2
/10
Last Scanned on 2025-03-10
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More