Discuss Scratch
- Discussion Forums
- » Open Source Projects
- » I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Hello!
I use Scratch to introduce young children to programming. My beginner students often have issues with code like this:
or like this:
In normal Scratch, this code won't do anything, because Scratch only updates the screen at the end of a loop, or after a wait block. While this makes sense from an optimization perspective, it's very confusing for my students! It would be much clearer if Scratch always updated the screen immediately following a visual change.
This was really really bothering me, so I grabbed Scratch's code off of Github and changed it! I'm really happy with how this works, and I think it would help my students a great deal!
The only problem is, the open source “Scratch GUI” project on Github can only save and load projects locally. That's a nonstarter for my classes, where the children usually use a different Chromebook each week. I'm not a backend developer, so I'm a little concerned this will be the end of the road.
Is there any preexisting code for hooking up Scratch to a backend system? I'd want something as simple as possible—I'm not looking to scale up to a zillion users! I don't even necessarily need an account/login system (although that would definitely be ideal), just something where students can save a project with a unique name and retrieve it later.
I use Scratch to introduce young children to programming. My beginner students often have issues with code like this:
when green flag clicked
forever
hide
show
end
or like this:
when green flag clicked
forever
move (10) steps
move (-10) steps
end
In normal Scratch, this code won't do anything, because Scratch only updates the screen at the end of a loop, or after a wait block. While this makes sense from an optimization perspective, it's very confusing for my students! It would be much clearer if Scratch always updated the screen immediately following a visual change.
This was really really bothering me, so I grabbed Scratch's code off of Github and changed it! I'm really happy with how this works, and I think it would help my students a great deal!
The only problem is, the open source “Scratch GUI” project on Github can only save and load projects locally. That's a nonstarter for my classes, where the children usually use a different Chromebook each week. I'm not a backend developer, so I'm a little concerned this will be the end of the road.
Is there any preexisting code for hooking up Scratch to a backend system? I'd want something as simple as possible—I'm not looking to scale up to a zillion users! I don't even necessarily need an account/login system (although that would definitely be ideal), just something where students can save a project with a unique name and retrieve it later.
Last edited by Wowfunhappy (Sept. 5, 2022 16:24:36)
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Unfortunately, Scratch's backend is not open source, so this will be hard to implement. If your change is not too big, you might want to try to implement it as a browser extension or something similar so it works with the Scratch backend in the Scratch editor. Just note that Scratch has a no-sharing-browser-extensions policy.
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
After reading your code, I realized it would probably be hard to insert a hook into Scratch-VM. I did develop some backends (though I'm only 13, so not any good backends that are free of security bugs
), but overall, it's hard to create a backend that you can safely upload files and implement user control simply.
If you would like to make a backend:
I recommend Django, because I still don't like JavaScript (though es6 is getting better). You should implement the assets/project endpoints like this forum post indicates.
If you don't:
This is a much better option. Since you're using Google already, make a Google App, and save projects using Google Drive (auth docs). Easy and simple.

If you would like to make a backend:
I recommend Django, because I still don't like JavaScript (though es6 is getting better). You should implement the assets/project endpoints like this forum post indicates.
If you don't:
This is a much better option. Since you're using Google already, make a Google App, and save projects using Google Drive (auth docs). Easy and simple.
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
this forum post indicates.You should implement the assets/project endpoints like
Oh perfect, I can just do a POST request!
Thanks, I might actually just use a CloudFlare worker.
And yeah, not going for security here!
Last edited by Wowfunhappy (June 20, 2022 18:48:12)
- ScratchcatandGobo
-
1000+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
you can with Scratch API, if your talking about stats.
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Okay, nope, I am so completely confused!
I can see that `assetHost` and `projectHost` are set in `src/lib/project-fetcher-hoc.jsx`. But they're already set to the official Scratch website.
It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
Is any of this documented anywhere? Hopefully it doesn't live in scratch-www, that would likely be a nightmare. I don't need the entire website…
I can see that `assetHost` and `projectHost` are set in `src/lib/project-fetcher-hoc.jsx`. But they're already set to the official Scratch website.
It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
Is any of this documented anywhere? Hopefully it doesn't live in scratch-www, that would likely be a nightmare. I don't need the entire website…
Last edited by Wowfunhappy (June 23, 2022 22:35:54)
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
I can get the save option to appear by setting `canSave` to `{true}` in `src/playground/render-gui.jsx`, but clicking the save button doesn't seem to do anything whatsoever, including show an error.
I set `projectHost` and `assetHost` to the URL of a Cloudflare worker I set up, but that worker isn't getting any hits whatsoever. This is also after I tested in Chromium with the `–disable-web-security` flag set to ensure there was no possibility of CORS or TLS restrictions getting in the way.
I set `projectHost` and `assetHost` to the URL of a Cloudflare worker I set up, but that worker isn't getting any hits whatsoever. This is also after I tested in Chromium with the `–disable-web-security` flag set to ensure there was no possibility of CORS or TLS restrictions getting in the way.
- CST1229
-
1000+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
I think it's scratch-www telling scratch-gui the parameters to enable cloud saving. It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
Last edited by CST1229 (June 24, 2022 17:29:05)
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
I think the project saving logic may be in scratch-gui since it seems to be in project-saver-hoc. It seems that MenuBar should have an onClickSave prop but I can't find any trace of it in scratch-gui when searching. There seems to be a dispatch type “manualUpdateProject” but I can't find what that triggers eitherI think it's scratch-www telling scratch-gui the parameters to enable cloud saving. It's not clear to me what mechanism is telling scratch-gui “I am not a real instance of Scratch” and subsequently disabling cloud saving / account login / etc. I need to understand what's missing, so I can go through and possibly re-implement it.
- ScratchcatandGobo
-
1000+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
OH!!! try using embed links. the code can be found here:
<iframe src="https://scratch-mit-edu.ezproxyberklee.flo.org/projects/652932390/embed“ allowtransparency=”true“ width=”485“ height=”402“ frameborder=”0“ scrolling=”no" allowfullscreen></iframe>its in html
Last edited by ScratchcatandGobo (June 25, 2022 15:15:11)
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
I'm making progress!
I had to set canCreateNew to true in render-gui.jsx. Then my Cloudflare worker started getting hits.
When Scratch starts, it tries to save the new project to the backend server. If that fails, it won't attempt to use the backend at any point in the future…
I had to set canCreateNew to true in render-gui.jsx. Then my Cloudflare worker started getting hits.
When Scratch starts, it tries to save the new project to the backend server. If that fails, it won't attempt to use the backend at any point in the future…
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Sorry, but this topic is about discussing a fork of the Scratch editor, OH!!! try using embed links. the code can be found here:not html snippets for embedding Scratch. That snippet is a) for embedding the project player with scratch-www, and this is more about scratch-gui, and b) this is more jsx rather than html. Thanks for trying to help!<iframe src="https://scratch-mit-edu.ezproxyberklee.flo.org/projects/652932390/embed“ allowtransparency=”true“ width=”485“ height=”402“ frameborder=”0“ scrolling=”no" allowfullscreen></iframe>its in html
Ah, interesting. So Scratch tries the create request first on the playground? If you want to try the GET request, maybe try localhost:port/#project-id-here to load a project, to see where the request ends up on your backend. I'm making progress!
I had to set canCreateNew to true in render-gui.jsx. Then my Cloudflare worker started getting hits.
When Scratch starts, it tries to save the new project to the backend server. If that fails, it won't attempt to use the backend at any point in the future…
Last edited by ZZC12345 (July 1, 2022 07:21:19)
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Ah, interesting. So Scratch tries the create request first on the playground? If you want to try the GET request, maybe try localhost:port/#project-id-here to load a project, to see where the request ends up on your backend.
Ah, yes, adding #project-id at the end of the URL sends the GET request! Thank you, I've been stuck at this point for several days!
- hacktronics
-
100+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Not sure, writing a scratch server backend, is a good idea. I don't like that design. I haven't look much at the server saving code, because creating a separate server would make my project uneconomical and I found scratch code not good enough for me.
Instead for https://ide.codeskool.cc/ , I rewrote the client itself to save it to firebase (not using any of the scratch saving & server logic), rather than implementing a separate server and figuring out the scratch communications. May be, if your problem is simple, then you don't need complex solutions. For me, saving to firebase directly from client, removes server and costly bills for me, while making the app even more fault tolerant to server crashes.
Again that my preference, as Scratch is too big, for them having there own servers makes sense, and every problem is different, I am just talking about my use case.
Instead for https://ide.codeskool.cc/ , I rewrote the client itself to save it to firebase (not using any of the scratch saving & server logic), rather than implementing a separate server and figuring out the scratch communications. May be, if your problem is simple, then you don't need complex solutions. For me, saving to firebase directly from client, removes server and costly bills for me, while making the app even more fault tolerant to server crashes.
Again that my preference, as Scratch is too big, for them having there own servers makes sense, and every problem is different, I am just talking about my use case.
Last edited by hacktronics (Aug. 21, 2022 15:50:20)
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
For what it's worth, I did get this fully working. I'm using Scratch's saving/loading code alongside a Cloudflare worker to handle requests, and Google Firebase for storage. I had to use a bit of a hack to store the project title and username—I think this metadata is normally handled by scratch-www rather than scratch-gui—but other than that, my implementation is relatively clean.
For security reasons, I'm hesitant to post the code publicly. However, if anyone else needs a setup like this, please get in touch and I'll do my best to provide guidance!
For security reasons, I'm hesitant to post the code publicly. However, if anyone else needs a setup like this, please get in touch and I'll do my best to provide guidance!
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Congratulations! I hope it's working smoothly! For what it's worth, I did get this fully working. I'm using Scratch's saving/loading code alongside a Cloudflare worker to handle requests, and Google Firebase for storage. I had to use a bit of a hack to store the project title and username—I think this metadata is normally handled by scratch-www rather than scratch-gui—but other than that, my implementation is relatively clean.
Yes, you're right about the metadata. It's handled by the Scratch API (https://mv-ezproxy-com.ezproxyberklee.flo.org), not the Scratch Project Host (https://mv-ezproxy-com.ezproxyberklee.flo.org) or the Asset Host (https://mv-ezproxy-com.ezproxyberklee.flo.org). Usually, the title is stored in the filename when the project is saved to a computer, and since it's offline, there's no need for a username.
Hypothetically, if anything, posting it on GitHub won't be a security hazard as long as you don't post the IP or hostname.
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
I don't suppose anyone knows where the code is in Scratch to handle saving screenshots?
I'd thought I could do without screenshots, but—surprise!—It turns out first graders are quite bad at remembering to title their programs. Shocking, I know!
Screenshots would help them tell all the versions of “Untitled Project” apart from each other, if it's not too hard to do…
I'd thought I could do without screenshots, but—surprise!—It turns out first graders are quite bad at remembering to title their programs. Shocking, I know!
Screenshots would help them tell all the versions of “Untitled Project” apart from each other, if it's not too hard to do…
Last edited by Wowfunhappy (Oct. 19, 2022 15:15:15)
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
For the stage, or for the workspace? For the stage, it's as simple as calling I don't suppose anyone knows where the code is in Scratch to handle saving screenshots?
I'd thought I could do without screenshots, but—surprise!—It turns out first graders are quite bad at remembering to title their programs. Shocking, I know!
Screenshots would help them tell all the versions of “Untitled Project” apart from each other, if it's not too hard to do…
Examplebut for the workspace, it gets harder, though you can look at the implementation of some of the screenshot parts of a specific browser extension I'm not allowed to name (try googling “scratch extension”).canvas.toDataURL(); // or await canvas.toBlob();
As for where it is in Scratch, I found something in scratch-render:
LLK/scratch-render/src/RenderWebGL.js L2000and this is used by getProjectThumbnail:/** * @param {snapshotCallback} callback Function called in the next frame with the snapshot data */ requestSnapshot (callback) { this._snapshotCallbacks.push(callback); }
LLK/scratch-gui/src/lib/project-saver-hoc.jsx L280It seems to be handled by onUpdateProjectThumbnail in ProjectSaverHOC. Maybe try attaching a callback somewhere there?getProjectThumbnail (callback) { this.props.vm.postIOData('video', {forceTransparentPreview: true}); this.props.vm.renderer.requestSnapshot(dataURI => { this.props.vm.postIOData('video', {forceTransparentPreview: false}); callback(dataURI); }); this.props.vm.renderer.draw(); }
Also, it would be great if this was open-sourced

Last edited by ZZC12345 (Oct. 20, 2022 06:03:38)
- Wowfunhappy
-
27 posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
For the stage, or for the workspace? For the stage, it's as simple as callingExamplecanvas.toDataURL(); // or await canvas.toBlob();
Thank you, I think that's all I need! (Just the stage is fine, goal is to have thumbnails like “My Stuff” in official Scratch.)
Also, it would be great if this was open-sourced– I want to take a look at the finished code
Unfortunately, I don't want to post all the code publicly for security reasons right now. While it's true there's no direct danger, I'm not a backend engineer, so I want to maintain some security-through-obscurity as an extra precaution. However, I absolutely don't want to hoard this either, and I'd be happy to answer questions and share specific code snippets if there's anything you're curious about. I can also share code with anyone who tracks me down and reaches out privately.

Last edited by Wowfunhappy (Oct. 22, 2022 20:52:20)
- ZZC12345
-
500+ posts
I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?
Great! If you care about implementing it “correctly”, you can also use the other methods I wrote about.For the stage, or for the workspace? For the stage, it's as simple as callingExamplecanvas.toDataURL(); // or await canvas.toBlob();
Thank you, I think that's all I need! (Just the stage is fine, goal is to have thumbnails like “My Stuff” in official Scratch.)
That's fine, I was just curious. Good luck!Also, it would be great if this was open-sourced– I want to take a look at the finished code
Unfortunately, I don't want to post all the code publicly for security reasons right now. While it's true there's no direct danger, I'm not a backend engineer, so I want to maintain some security-through-obscurity as an extra precaution. However, I absolutely don't want to hoard this either, and I'd be happy to answer questions and share specific code snippets if there's anything you're curious about. I can also share code with anyone who tracks me down and reaches out privately.
- Discussion Forums
- » Open Source Projects
-
» I made a small Scratch fork to be more intuitive for young children. Is there a (relatively) easy way to implement saving/loading projects to the cloud?