TurboWarp Desktop is Scratch in an Electron shell
A better offline editor for Scratch 3.
At a glance
- What is it?
- TurboWarp Desktop is a GPL-3.0 Electron application that runs the TurboWarp Scratch 3 editor offline, and the interesting part of its documentation is the explanation of why a Scratch editor needs four different renderer processes and a webpack build for some of them.
- Who is it for?
- TurboWarp Desktop fits someone who wants the Scratch 3 editor as a local desktop application, offline, with the TurboWarp extensions and a compiler, and it fits a developer who wants to read how a serious Electron app separates an unbuilt main process from a bundled renderer. It does not fit a school that needs the hosted editor with accounts and shared projects, since the desktop app is a local editor with no account system described here.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
An offline Scratch editor, and where the downloads are
TurboWarp Desktop is TurboWarp as a desktop app, described in the repository description as a better offline editor for Scratch 3, and the package metadata gives the longer version: a Scratch mod with a compiler, dark mode, a bunch of addons, and more.
The README is brief because the project is not trying to sell you anything. It points you to desktop.turbowarp.org for the downloads, states that it is licensed under the GPLv3.0 with the LICENSE file for more information, and notes that parts of the repository are based on LLK/scratch-desktop, which is the Electron shell that the official Scratch desktop editor is built on. So the lineage is clear: this is the Scratch desktop application, carrying a modified editor.
The scratch-gui dependency in the package metadata makes that concrete, and it is a fork rather than the upstream: scratch-gui points at github:TurboWarp/scratch-gui#develop, and the extensions come from github:TurboWarp/extensions#master. The forks are how the compiler, the dark mode and the addons get into the editor, and they are why the build fetches extra files rather than assuming they are on disk.
The author is Thomas Weber, the version in the tree is 1.16.0, and the project is CommonJS with a single runtime dependency, semver, and everything else in devDependencies. That is unusual for an Electron app and it reflects the architecture described below, where most of the code is bundled at build time rather than shipped as installed packages.
Four processes, because custom extensions have security requirements
The README states the reason for the complexity first: due to the security requirements mandated by custom extensions existing, the desktop app is significantly more complicated than Scratch's. Then it describes the pieces.
src-main is what runs in Electron's main process. There is no build step, and this code is included as is, with src-main/entrypoint.js as the entry point to the entire app.
src-renderer-webpack runs in an Electron renderer process to make the editor work, and this one is built by webpack into dist-renderer-webpack. src-renderer also runs in an Electron renderer process but without webpack, and it is used for things like the privacy policy window. src-preload runs as preload scripts in an Electron renderer process, and they export glue functions to allow the renderer and the main process to talk to each other in a somewhat controlled manner.
Finally, dist-library-files and dist-extensions contain additional static resources managed by npm run fetch.
The split is the interesting part. A renderer that loads third-party extension code cannot be trusted the way a bundled one can, so the editor itself is compiled and shipped as static files while the windows that display untrusted content are not, and the preload script is the only sanctioned channel between them. The word somewhat in the description of the glue functions is the honest part, since preload scripts are a well known weak point in the Electron security model.
The command sets you repeat on every pull
Development needs submodules, so the clone is recursive:
git clone --recursive https://github.com/TurboWarp/desktop turbowarp-desktopor, after a plain clone, the two submodule commands:
git submodule init
git submodule updateThen the dependencies, installed with npm ci so that the lock file is honoured exactly:
npm ciAnd then the extra files, which are not in the repository:
npm run fetchThe fetch script is three steps in one, as the package metadata shows: it runs scripts/download-library-files.mjs, then scripts/download-packager.mjs, then scripts/prepare-extensions.mjs. The library files, the packager and the extension files are all downloaded rather than committed, which is why the fetch step exists and why it has to be repeated.
And the README is explicit that the three previous sets of commands must be repeated every time you pull changes from GitHub. That is the friction of a repository that keeps a large amount of static content outside version control, and it is worth knowing before you start: a contributor who pulls and forgets will find that the editor is missing pieces and will spend an hour looking for a bug that is really a missing fetch.
Two terminals, one watcher and one Electron
Once everything is compiled and fetched, you can start a development Electron instance:
npm run electron:startwhich is, in the package metadata, electron src-main/entrypoint.js.
For the webpack portions, which is where the editor lives, there is a compile step for a one-off build:
npm run webpack:compileand a watch mode that rebuilds as you change files:
npm run webpack:watchThe README recommends the two terminal arrangement explicitly: development works pretty well if you open two terminals side by side and run npm run webpack:watch in one and npm run electron:start in the other. You can then refresh the windows with ctrl+R or cmd+R for renderer file changes to apply, and manually restart the app for main file changes to apply.
That last detail is the price of the architecture in the previous section. Because the renderer is a bundle served from disk, a change to it is a rebuild and a refresh, while a change in the main process needs the whole application restarted. It is a slower loop than a typical web app, where a hot reload replaces the module, and it is the direct consequence of not running the editor as one page with a dev server.
One Linux caveat is mentioned: the app icon will not work in the development version, but it will work in the packaged version.
The Linux sandbox helper error, and why it does not affect users
One troubleshooting section is worth reading in full, because it is a real problem that a new contributor on a current Ubuntu will hit.
On some Linux distributions, Electron will crash with a message that the SUID sandbox helper binary was found but is not configured correctly, and that rather than run without sandboxing the app is aborting. The fix is to make sure that the chrome-sandbox binary in node_modules/electron/dist is owned by root and has mode 4755. The README notes seeing this on Debian 10 and earlier and on Ubuntu 24.04 and later.
For development, two commands are given, one to enable unprivileged user namespaces and one to stop AppArmor from preventing unprivileged user namespace creation by default, with a note that the second can be ignored if the distribution does not use AppArmor:
# Enable unprivileged user namespaces.
sudo sysctl -w kernel.unprivileged_userns_clone=1
# Stop AppArmor from preventing unprivileged user namespace creation by default.
# If your distribution does not use AppArmor then you can ignore the error.
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0The guidance afterwards is the right one. There are ways to make the setting permanent, but the project does not think you should be making permanent kernel configuration changes just to develop the app, and the error will not happen in the final .deb package, Flathub or Snap Store releases.
That is the shape of the whole section: a development machine problem, with a temporary workaround, and an explicit statement that the shipped artifacts are unaffected. A reader who skips it will meet the error on the first run of npm run electron:start on a current Ubuntu.
Packaging for three platforms and the signing story
Production builds need the webpack portions optimised first, with npm run webpack:prod, which the package metadata shows as a production environment build through cross-env and webpack. The development version of the app will be larger and slower than the final release builds.
Packaging is then done either with the project's own build script, release-automation/build.mjs, whose README explains the details, or with the electron-builder CLI, and the README gives the three examples directly:
# You can also do manual builds with electron-builder's CLI, for example:
# Windows installer
npx electron-builder --windows nsis --x64
# macOS DMG
npx electron-builder --mac dmg --universal
# Linux Debian
npx electron-builder --linux debThe constraint that catches people is stated right after: you can typically only package for a certain operating system while on that operating system. The Windows installer is an NSIS package, the macOS build is a universal DMG covering both architectures, and the Linux build is a deb.
Signing is handled for free. TurboWarp Desktop uses a free code signing service provided by SignPath.io, with the certificate from the SignPath Foundation, and the approver listed is GarboMuffin, along with the privacy policy URL. The repository carries a store-listings/ directory, a debian/ directory and a linux-files/ directory, which is where the metadata for the Flathub and Snap Store listings and the Debian packaging lives.
The reason a free signing service matters here is worth stating plainly. An unsigned desktop application triggers warnings on every platform it is installed on, and for an application that a child or a teacher downloads, those warnings are the difference between a tool people use and a tool people cannot.
Custom scripts and styles without rebuilding the app
The last feature worth understanding is that TurboWarp Desktop lets you configure custom JavaScript and CSS without rebuilding the application.
You find the data path either from the list in the documentation or by clicking the question mark in the top right corner, then Desktop Settings, then Open User Data, and opening the highlighted folder. The paths are:
- Windows (except Microsoft Store): `%APPDATA%/turbowarp-desktop`
- Microsoft Store: Open `%LOCALAPPDATA%/Packages`, find the folder with the word `TurboWarpDesktop` in it, then open `LocalCache/Roaming/turbowarp-desktop`
- macOS (except Mac App Store): `~/Library/Application Support/turbowarp-desktop`
- Linux (except Flatpak and Snap): `~/.config/turbowarp-desktop`In that folder you create a file called userscript.js to configure custom JavaScript, and a file called userstyle.css to configure custom CSS. Completely restarting TurboWarp Desktop, including all windows, is then required to apply them.
The list is a good illustration of how a desktop application accumulates packaging variations, since the same data directory has four different locations depending on the store the app came from, with the macOS App Store case adding a container path and the Linux Flatpak and Snap cases adding their own variations. The Full restart requirement is also typical, because a userscript has to be injected into the renderer before the editor loads.
The uninstall instructions are on the project website rather than in the README, which is the one piece of the documentation that lives elsewhere.
Editorial conclusion
TurboWarp Desktop fits someone who wants the Scratch 3 editor as a local desktop application, offline, with the TurboWarp extensions and a compiler, and it fits a developer who wants to read how a serious Electron app separates an unbuilt main process from a bundled renderer. It does not fit a school that needs the hosted editor with accounts and shared projects, since the desktop app is a local editor with no account system described here. Before building it, follow the three command sets in order and run them again after every pull, and if you hit the Linux sandbox helper error, read that section before changing kernel settings, because the shipped packages do not have the problem.
Frequently asked questions
How do I set up a development environment for TurboWarp Desktop?
Clone the repository with git clone --recursive, or run git submodule init and git submodule update, then install the dependencies with npm ci and fetch the extra library, packager and extension files with npm run fetch. The README says to repeat those three sets of commands every time you pull changes.
What are the four source directories in TurboWarp Desktop for?
src-main runs in the Electron main process with no build step and entrypoint.js as the entry point, src-renderer-webpack is built by webpack into dist-renderer-webpack to make the editor work, src-renderer runs in a renderer without webpack for things like the privacy policy window, and src-preload runs as preload scripts exporting glue functions between renderer and main.
How do I fix the SUID sandbox helper error on Linux?
Electron aborts because the chrome-sandbox binary is not owned by root with mode 4755. For development you can enable unprivileged user namespaces with sysctl -w kernel.unprivileged_userns_clone=1 and disable the AppArmor restriction with sysctl -w kernel.apparmor_restrict_unprivileged_userns=0, and the README notes the error does not happen in the final deb package, Flathub or Snap Store releases.
How do I build a production package?
Optimise the webpack portions with npm run webpack:prod, then package with the release-automation/build.mjs script or the electron-builder CLI, for example npx electron-builder --windows nsis --x64, npx electron-builder --mac dmg --universal or npx electron-builder --linux deb. You can typically only package for the operating system you are on.
How do I add my own JavaScript or CSS?
Create userscript.js and userstyle.css in the TurboWarp Desktop data path for your platform, for example %APPDATA%/turbowarp-desktop on Windows or ~/.config/turbowarp-desktop on Linux, then completely restart the application including all windows to apply the changes.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/turbowarp-desktop)Was this useful?