Open-Source Wikis

/

Godot

/

Platforms

/

Web

godotengine/godot

Web

Purpose

platform/web/ builds Godot for the browser. The engine compiles to WebAssembly via Emscripten; a JavaScript shim handles canvas creation, audio, file system access via the IndexedDB-backed Emscripten FS, networking via fetch / WebSocket / RTCPeerConnection, and input events through DOM events. The result is a .wasm blob and a small loader (.html / .js / .pck) that runs in any modern browser.

Layout

platform/web/
├── godot_web.cpp                    main() entry compiled by Emscripten
├── os_web.{cpp,h}                   OS_Web subclass
├── display_server_web.{cpp,h}       Canvas + DOM event handling
├── audio_driver_web.{cpp,h}         Web Audio API driver
├── http_client_web.{cpp,h}          fetch()-based HTTP client
├── godot_js.h, godot_js_*.h         C↔JS function tables (cdecl-ish)
├── library_godot_*.js               JS-side helpers loaded by Emscripten
├── js/                              TypeScript editor + engine glue (compiled to JS by emscripten linking)
│   ├── engine/                      Engine.js bootstrap + project loader
│   └── editor/                      Editor-specific JS (file picker, drag-and-drop)
├── api/                             JavaScriptBridge: call JS from GDScript and vice versa
├── package.json                     npm + tsc setup for the JS sources
├── jsdoc2md/                        JSDoc → Markdown for the public JS API
├── export/                          Web exporter (HTML shell + WASM + PCK + service worker)
└── detect.py                        Emscripten toolchain detection

Build

scons platform=web target=template_release
scons platform=web target=editor                    # web-based editor (experimental / for sandboxes)

The build invokes emcc / em++ from Emscripten 3.1.62+. The output goes into bin/godot.web.template_release.wasm32.{wasm,js,html} (and matching debug variants).

Display server

DisplayServerWeb (display_server_web.cpp) attaches to an HTML canvas. It:

  • Resizes the canvas to match Viewport dimensions (with optional pixel ratio handling for HiDPI).
  • Routes DOM events (mousedown, mousemove, wheel, keydown, pointerdown, pointercancel, …) into InputEvents.
  • Supports Pointer Lock for mouse-look games.
  • Supports the Gamepad API for joypads.
  • Exposes the Fullscreen API via Window::set_mode(WINDOW_MODE_FULLSCREEN).
  • Implements clipboard via the async navigator.clipboard.* API (with a fallback path through document.execCommand).
  • Routes touch events (touchstart/touchmove/touchend) for mobile browsers.

Rendering

Web uses the Compatibility renderer by default — it targets WebGL 2 via the drivers/gles3/ backend. WebGPU support is in progress in the engine but not yet the default.

Threaded rendering depends on the pthreads Emscripten flag (which requires COOP/COEP HTTP headers from the host). When threads are unavailable, the engine runs everything on the main browser thread.

Audio

audio_driver_web.cpp wraps the Web Audio API. The mixing happens in an AudioWorklet (or ScriptProcessorNode on legacy browsers) driven by the engine's mix loop.

File system

Emscripten provides a virtual file system that maps to:

  • MEMFS for transient files.
  • IDBFS (IndexedDB) for persistent user data.

OS_Web configures IDBFS as the user data dir and flushes writes asynchronously. The PCK ships as part of the page payload (or is fetched lazily via --main-pack).

JavaScript bridge

api/ exposes JavaScriptBridge to GDScript:

JavaScriptBridge.eval("alert('hi')")
var window = JavaScriptBridge.get_interface("window")
var location = window.location.href
JavaScriptBridge.create_callback(my_callback).bind_to_window("onresize")

The bridge marshals arguments through Emscripten's value-typed arguments (numbers, strings, objects). Callbacks travel both directions.

Networking

  • HTTPhttp_client_web.cpp wraps fetch(). Some headers are inaccessible due to browser CORS rules; the engine documents the limitations.
  • WebSocket — uses the browser's WebSocket (in modules/websocket/web_socket_peer_web.cpp), which is the only way to do binary network IO in the browser.
  • WebRTC — the webrtc module provides WebRTCPeerConnection over the browser API for peer-to-peer.
  • No raw TCP/UDP — browsers don't expose them. ENet is unavailable in web builds.

Export

export/export_plugin.cpp packages a project for the web:

  • Generates an HTML "shell" (replaceable with a custom template).
  • Bundles the WASM, JS loader, PCK, and (optionally) a Web App Manifest.
  • Generates a service worker for offline + caching support.
  • Configures COOP/COEP headers documentation if threads=yes is selected.

The default shell is plain — most projects ship a customized HTML template.

Limitations

  • File access outside the IDBFS sandbox requires user-initiated prompts (the File System Access API where supported).
  • Some plugins / native modules (e.g., the Mono module) have limited or experimental web support.
  • Audio latency is at the mercy of the browser's Web Audio scheduling.
  • Memory is bounded by the WASM heap size; large projects must tune the build's INITIAL_MEMORY and ALLOW_MEMORY_GROWTH flags.

Key abstractions

Abstraction File Role
OS_Web platform/web/os_web.cpp OS subclass over Emscripten
DisplayServerWeb platform/web/display_server_web.cpp Canvas + DOM input
AudioDriverWeb platform/web/audio_driver_web.cpp Web Audio API
HTTPClientWeb platform/web/http_client_web.cpp fetch()-based HTTP
JavaScriptBridge platform/web/api/javascript_bridge.cpp GDScript ↔ JS
EditorExportPlatformWeb platform/web/export/export_plugin.cpp Web exporter

Entry points for modification

  • Custom HTML shell → drop your file in the project and select it in the export preset.
  • New JS API call → add an extern declaration in godot_js_*.h, implement in library_godot_*.js, and bind from JavaScriptBridge.
  • WebGPU experimentation → look at drivers/gles3/ for the Compatibility-style backend; a future WebGPU driver would slot into the same RendererCompositor interface.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Web – Godot wiki | Factory