From 42 MB3 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-corp and Cross-Origin-Opener-Policy: same-origin if 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

  • emcc on PATH is the gatekeeper – without it, platform=web doesn’t exist.
  • A 20‑line custom.py can 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 MB3 MB: compiling lean Godot Web templates with emcc From 42 MB3 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-corp and Cross-Origin-Opener-Policy: same-origin if 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

  • emcc on PATH is the gatekeeper – without it, platform=web doesn’t exist.
  • A 20‑line custom.py can 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