From 42 MB → 3 MB: compiling lean Godot Web templates with emcc
Everything I wish I’d known before wasting an evening yelling at
scons platform=list.
1. Why bother?
A vanilla Godot 4.4 Web export weighs ≈ 42 MB uncompressed and still ≈ 9 MB zipped – not great for impatient players on itch.io or low‑cost mobile data plans. Re‑building the export template yourself lets you strip every feature you don’t use and cut that number by an order of magnitude.
2. The missing dependency: emcc
Godot’s Web platform is Wasm + JS produced by Emscripten.
If SCons can’t find emcc, the only platform it offers is windows, which is why the cryptic error appears.
Requirements to compile Web templates • Emscripten ≥ 3.1.62 • Python ≥ 3.8 • SCons ≥ 4.0
Quick setup (Windows example)
git clone https://github.com/emscripten-core/emsdk C:\emsdk
cd C:\emsdk
emsdk install 3.1.62
emsdk activate 3.1.62
emsdk_env.bat # makes emcc visible *in this shell*
where emcc # should print a path now
Open a new terminal? Run emsdk_env.bat again – the PATH addition isn’t permanent.
3. Building the templates
cd C:\godot\source
scons platform=web target=template_debug -j8
scons platform=web target=template_release -j8
The two ZIPs in bin\ become your Custom Debug/Release Template in Editor Settings → Export → Web.
4. My minimal profile (custom.py)
Popcar’s excellent size‑reduction guide inspired my own profile. I started from their script and tweaked a couple of flags:
# custom.py
target = "template_release"
debug_symbols = "no"
optimize = "size"
lto = "full"
# trim features
module_text_server_adv_enabled = "no"
module_text_server_fb_enabled = "yes"
disable_advanced_gui = "yes"
# throw out 3D, XR, Vulkan, ZIP, deprecated APIs…
deprecated = "no"
vulkan = "no"
use_volk = "no"
openxr = "no"
minizip = "no"
# enable only the modules I really use
modules_enabled_by_default = "no"
module_gdscript_enabled = "yes"
module_freetype_enabled = "yes"
module_svg_enabled = "yes"
module_webp_enabled = "yes"
module_godot_physics_2d_enabled = "yes"
Build with:
scons platform=web profile=custom.py
Result: 24.8 MB uncompressed / ≈ 5 MB zipped.
5. Going even smaller with a .build file
Godot’s Engine Compilation Configuration Editor (Project → Tools) can generate a per‑project .build file that disables individual nodes/resources.
After hand‑fixing the over‑eager auto‑detect list, compiling with:
scons platform=web profile=custom.py build_profile=jion-web.build
dropped the template to ≈ 17 MB raw / ≈ 3.7 MB zipped.
(Remove one class too many and the game crashes on launch – keep a backup!)
6. Optional post‑processing
| Trick | Size gain | Gotchas |
|---|---|---|
wasm-opt -Oz |
−1–2 MB | slow; minor benefit after ZIP |
Brotli‑pre‑compress .wasm/.pck |
transfer as low as 2.7 MB | host must serve br encoding |
7. Hosting checklist
- Serve over HTTPS with
Cross-Origin-Embedder-Policy: require-corpandCross-Origin-Opener-Policy: same-originif you enabled threads or GDExtension. - Always gzip/Brotli large static files (
.wasm,.pck). - For itch.io just upload the zipped export; their backend handles compression & headers.
8. Take‑aways
emccon PATH is the gatekeeper – without it,platform=webdoesn’t exist.- A 20‑line
custom.pycan cut > 80 % of the default template. - The new Compilation Configuration Editor is powerful but fragile; test every flag.
- Past ~3 MB zipped the rest of your download budget is usually assets, not engine.
Happy shrinking! If you publish something cool with these tips, ping me on jion.in – I’d love to see it.
Further reading
-
Popcar – “How to Minify Godot’s Build Size (93 MB → 6.4 MB exe)” https://popcar.bearblog.dev/how-to-minify-godots-build-size/
-
Godot Docs – “Compiling for the Web” https://docs.godotengine.org/en/stable/tutorials/export/web/exporting_for_web.html
-
From 42 MB → 3 MB: compiling lean Godot Web templates with emcc From 42 MB → 3 MB: compiling lean Godot Web templates with emcc
Everything I wish I’d known before wasting an evening yelling at
scons platform=list.
## 1. Why bother?
A vanilla Godot 4.4 Web export weighs ≈ 42 MB uncompressed and still ≈ 9 MB zipped – not great for impatient players on itch.io or low‑cost mobile data plans. Re‑building the export template yourself lets you strip every feature you don’t use and cut that number by an order of magnitude.
## 2. The missing dependency: emcc
Godot’s Web platform is Wasm + JS produced by Emscripten.
If SCons can’t find emcc, the only platform it offers is windows, which is why the cryptic error appears.
Requirements to compile Web templates • Emscripten ≥ 3.1.62 • Python ≥ 3.8 • SCons ≥ 4.0
### Quick setup (Windows example)
powershell
git clone https://github.com/emscripten-core/emsdk C:\emsdk
cd C:\emsdk
emsdk install 3.1.62
emsdk activate 3.1.62
emsdk_env.bat # makes emcc visible *in this shell*
where emcc # should print a path now
Open a new terminal? Run emsdk_env.bat again – the PATH addition isn’t permanent.
## 3. Building the templates
powershell
cd C:\godot\source
scons platform=web target=template_debug -j8
scons platform=web target=template_release -j8
The two ZIPs in bin\ become your Custom Debug/Release Template in Editor Settings → Export → Web.
## 4. My minimal profile (custom.py)
Popcar’s excellent size‑reduction guide inspired my own profile. I started from their script and tweaked a couple of flags:
```python # custom.py target = "template_release" debug_symbols = "no" optimize = "size" lto = "full"
# trim features module_text_server_adv_enabled = "no" module_text_server_fb_enabled = "yes" disable_advanced_gui = "yes"
# throw out 3D, XR, Vulkan, ZIP, deprecated APIs… deprecated = "no" vulkan = "no" use_volk = "no" openxr = "no" minizip = "no"
# enable only the modules I really use modules_enabled_by_default = "no" module_gdscript_enabled = "yes" module_freetype_enabled = "yes" module_svg_enabled = "yes" module_webp_enabled = "yes" module_godot_physics_2d_enabled = "yes" ```
Build with:
powershell
scons platform=web profile=custom.py
Result: 24.8 MB uncompressed / ≈ 5 MB zipped.
## 5. Going even smaller with a .build file
Godot’s Engine Compilation Configuration Editor (Project → Tools) can generate a per‑project .build file that disables individual nodes/resources.
After hand‑fixing the over‑eager auto‑detect list, compiling with:
powershell
scons platform=web profile=custom.py build_profile=jion-web.build
dropped the template to ≈ 17 MB raw / ≈ 3.7 MB zipped.
(Remove one class too many and the game crashes on launch – keep a backup!)
## 6. Optional post‑processing
| Trick | Size gain | Gotchas |
|---|---|---|
wasm-opt -Oz |
−1–2 MB | slow; minor benefit after ZIP |
Brotli‑pre‑compress .wasm/.pck |
transfer as low as 2.7 MB | host must serve br encoding |
## 7. Hosting checklist
- Serve over HTTPS with
Cross-Origin-Embedder-Policy: require-corpandCross-Origin-Opener-Policy: same-originif you enabled threads or GDExtension. - Always gzip/Brotli large static files (
.wasm,.pck). - For itch.io just upload the zipped export; their backend handles compression & headers.
## 8. Take‑aways
emccon PATH is the gatekeeper – without it,platform=webdoesn’t exist.- A 20‑line
custom.pycan cut > 80 % of the default template. - The new Compilation Configuration Editor is powerful but fragile; test every flag.
- Past ~3 MB zipped the rest of your download budget is usually assets, not engine.
Happy shrinking! If you publish something cool with these tips, ping me on jion.in – I’d love to see it.
### Further reading
- Popcar – “How to Minify Godot’s Build Size (93 MB → 6.4 MB exe)” https://popcar.bearblog.dev/how-to-minify-godots-build-size/
- Godot Docs – “Compiling for the Web” https://docs.godotengine.org/en/stable/tutorials/export/web/exporting_for_web.html
From tastygames_official reddit comment:
You can create a custom build profile which only uses the stuff you need: https://docs.godotengine.org/en/stable/tutorials/editor/using_engine_compilation_configuration_editor.html
So if you're doing 2D then it won't include all the 3D and OpenXR stuff and won't include any nodes you don't use. Use the "detect from project" button and then save the build profile. Then you need to compile FROM SOURCE and then you use that built file (it outputs to the godot-src/bin directory if I'm not mistaken) for your web build. Now you'll probably get some errors while building the runtime OR when exporting or running your exported game. Something like "missing NodeTypeXXX". So then you have to go back to the build profile configurator and add in NodeTypeXXX into the "forced classes on detect" box, then do everything all over again.
It's quite involved, but it could bring you down to 30 or even 20MB. Or maybe smaller - don't know. The smallest I've gotten a 3D game was ~25MB, but 2D games probably could get way smaller.
note: for building the web runtime you probably need to do:
scons platform=web target=template_release build_profile=/path/to/profile.gdbuild