Discuss Scratch
- Discussion Forums
- » Advanced Topics
- » Alternative to popular method of accessing scratch VM object that longer works
- MonkeyBean2
-
Scratcher
500+ posts
Alternative to popular method of accessing scratch VM object that longer works
The popular method of grabbing the scratch VM object from the project editor page no longer works (as of 2025-10-11):
(note: if someone remembers who made this originally, please tell me so I can credit them)
This was very useful for messing around with nonstandard project JSON – Once you have the VM object, use vm.toJSON() and vm.loadProject() to export/import the project in JSON form (much faster than downloading/uploading the .sb3 (although you can upload project.json directly)).
I have come up with a new method that appears to work (however I wouldn't be surprised if it breaks in the near future, as subtle changes could break it).
I found this by searching through the JSON objects of every HTML element on the project page for a key named ‘store’.
It uses .find() (.filter but it outputs only the first match) because the __reactFiber$… key has a random ID at the end.
note to ST: This code does not actually do anything, it merely indexes through the object tree to find the scratch-vm object.
let vm = document.getElementById('app')._reactRootContainer._internalRoot .current.child.pendingProps.store.getState().scratchGui.vm
This was very useful for messing around with nonstandard project JSON – Once you have the VM object, use vm.toJSON() and vm.loadProject() to export/import the project in JSON form (much faster than downloading/uploading the .sb3 (although you can upload project.json directly)).
I have come up with a new method that appears to work (however I wouldn't be surprised if it breaks in the near future, as subtle changes could break it).
let vm = Object.entries(document.getElementById('app').children[0]) .find(x=>x[0].startsWith("__reactFiber$"))[1].return.return.return.return .pendingProps.value.store.getState().scratchGui.vm
I found this by searching through the JSON objects of every HTML element on the project page for a key named ‘store’.
It uses .find() (.filter but it outputs only the first match) because the __reactFiber$… key has a random ID at the end.
note to ST: This code does not actually do anything, it merely indexes through the object tree to find the scratch-vm object.
- Maximouse
-
Scratcher
1000+ posts
Alternative to popular method of accessing scratch VM object that longer works
Here's a slightly shorter version:
let vm = Object.entries(document.getElementById('app')) .find(x=>x[0].startsWith("__reactContainer$"))[1].child .pendingProps.store.getState().scratchGui.vm
(note: if someone remembers who made this originally, please tell me so I can credit them)I believe it's by @completeness: https://scratch.mit.edu/discuss/post/6180624/
- Geotale
-
Scratcher
100+ posts
Alternative to popular method of accessing scratch VM object that longer works
Further shorter versions, found via thorough searching:
/// Option 1 Object.values(document.getElementById('app'))[0].child.updateQueue.lastEffect.deps[1].scratchGui.vm // Option 2, for fun Object.values(document.querySelector(".project-info-alerts").nextSibling.firstChild)[0].child.pendingProps.vm
- redspacecat
-
Scratcher
1000+ posts
Alternative to popular method of accessing scratch VM object that longer works
For reference, the original post got dust binned for some reason.(note: if someone remembers who made this originally, please tell me so I can credit them)I believe it's by @completeness: https://scratch.mit.edu/discuss/post/6180624/
It's still on ocular though: https://ocular.jeffalo.net/post/6180083
- nembence
-
Scratcher
500+ posts
Alternative to popular method of accessing scratch VM object that longer works
This feels more reliable than doing hard-coded property accesses, although I don't know if it really is. It seems to work on the project page, in the editor, and on the new scratch-gui website (it doesn't work on the old scratch-gui website because that has “__reactInternalInstance###” instead of “__reactFiber###”, but it works if you replace “/Fiber/” with “/Instance/” or “/Fiber|Instance/”)
Also here is a shortened version:
To get the “store” object replace all “vm”-s in the code with “store”
let fiber=Object.entries(document.querySelector('[class*="stage-wrapper"]')).find(x=>/Fiber/.test(x))[1]; while(!fiber.pendingProps.vm) fiber=fiber.return; let vm=fiber.pendingProps.vm;
Also here is a shortened version:
let vm = (a=>a=f=>f.pendingProps.vm||a(f.return))()( Object.entries(document.querySelector('[class*="stage-wrapper"]')).find(x=>/Fiber/.test(x))[1] );
To get the “store” object replace all “vm”-s in the code with “store”
- Discussion Forums
- » Advanced Topics
-
» Alternative to popular method of accessing scratch VM object that longer works




