June 27, 2026
6 min read
Porting Half-Life 2 to the Browser: WebAssembly & WebGL2

Key Takeaways
- •The Miracle of WebAssembly: Half-Life 2 Natively in the Browser
- •The Porting Pipeline: Compiling C++ to the Web
- •Graphics Translation via ToGL and WebGL2
The Miracle of WebAssembly: Half-Life 2 Natively in the Browser
Running classic 3D games in a web browser is not entirely new. We have seen DOOM, Quake, and even early versions of Minecraft running on web pages. However, compiling a physics-heavy, complex AAA title like Valve's Half-Life 2 to run natively in a web browser with zero installations is a monumental technical achievement.
Recently, a high-school developer known as slqnt, in collaboration with developer 98006, released an impressive browser-based port of Half-Life 2 (accessible at hl2.slqnt.dev). Building upon previous community web-porting efforts—most notably a browser port of Portal created by developer weliveinhell—this project represents a fascinating case study in modern game engine compilation and web performance.
As a game developer, seeing the Source Engine running inside a browser tab is both surreal and highly educational. It showcases the incredible power of WebAssembly (WASM), WebGL2, and modern web compilation toolchains. Let’s take a look under the hood of how this port was made possible, the rendering pipeline, the file system virtualization, and the memory constraints that web game developers must overcome.
The Porting Pipeline: Compiling C++ to the Web
The core technology behind this port is Emscripten, an open-source compiler toolchain that compiles C and C++ code into WebAssembly. Since the Source Engine is written in C++, Emscripten is the natural choice for translating the engine's codebase into a format that browser engines (like V8 or JavaScriptCore) can execute at near-native speeds.
However, compilation is only half the battle. A game engine is a complex web of systems: rendering, audio, physics, and input. Porting these systems to the web requires mapping native APIs to their web equivalents.
Graphics Translation via ToGL and WebGL2
Source Engine was originally designed for Microsoft's Direct3D (DirectX 9) API on Windows. Direct3D cannot run directly in a browser. Fortunately, Valve did much of the heavy lifting years ago. When Valve ported Steam and its games to OS X and Linux, they developed ToGL, a translation layer that converts Direct3D 9 calls into OpenGL calls on the fly.
Because the Linux build of the Source Engine already had an OpenGL renderer, the web developers could leverage this work. Emscripten easily translates OpenGL ES 2.0/3.0 calls into WebGL/WebGL2. By targeting the Linux OpenGL codebase, the developers mapped the engine's graphics pipelines directly to the browser's GPU wrapper.
Here is how the graphics and compilation pipelines stack up:
This translation pipeline allows the browser to utilize the user's graphics hardware, achieving surprisingly high frame rates on standard desktop machines and even Chromebooks.
Streaming the World: Virtual Filesystems and VPKs
One of the largest hurdles in web game development is asset delivery. A typical installation of Half-Life 2 is several gigabytes. Users expect web pages to load in seconds, not hours. How can a game with massive map files, high-resolution textures, and hours of voice lines fit into a browser tab?
The answer lies in virtual filesystems and dynamic asset streaming.
Emscripten Filesystem Architecture
Emscripten provides virtual filesystem wrappers (like MEMFS and IDBFS) that emulate a standard POSIX filesystem in JavaScript. The game engine believes it is reading files from a local hard drive, but in reality, it is interacting with browser-managed virtual storage.
To keep the initial load times low, the port does not download the entire game at once. Instead, it streams assets in the background. The Source Engine packages its files (textures, sounds, maps, models) into `.vpk` (Valve Pack) files. The web port uses a custom streaming solution that requests specific chunks of these VPKs over HTTP as needed. When a player loads into a new map (like `d1_trainstation_01`), the virtual filesystem fetches the map file (`.bsp`), the required textures (`.vtf`), and the sound files on-demand.
Once downloaded, the browser utilizes IndexedDB (via Emscripten's IDBFS) to cache the assets locally on the user's machine. The next time the player runs the game, the files are loaded directly from local browser storage, bypassing the network entirely.
Overcoming the 32-bit WASM Memory Wall
While the port is incredibly performant, running a complex 3D engine in a browser environment introduces severe memory constraints.
WebAssembly is traditionally a 32-bit architecture. This means the WASM virtual machine is strictly limited to a 4GB address space. In practice, many modern browsers restrict a single tab's WebAssembly memory allocation even further—often to 2GB or less—to prevent out-of-memory crashes on the host system.
For a game like Half-Life 2, managing a 2GB memory budget is a constant challenge. The engine must store:
1. Compiled WebAssembly code and static data
2. The game heap (active physics objects, entity states, logic)
3. Texture buffers and vertex data loaded into RAM before being sent to the GPU
4. Decoded audio streams
To prevent browser crashes, the web port must implement aggressive asset unloading. When transitioning between maps, textures and models that are no longer in use must be purged from memory immediately. Any memory leaks in the engine's memory allocators (which were designed for systems with abundant RAM) will quickly lead to a crash.
Web Limitations and the Future of Web Gaming
As PC Gamer and other outlets have noted, the browser port of Half-Life 2 is not a flawless representation of the original game. It has minor graphical issues—such as missing textures on character eye models, giving NPCs a somewhat disturbing, "zombie-like" look. There are also occasional performance hitches when the engine streams assets in the background during gameplay.
Furthermore, because this port relies on leak-derived Source Engine codebases, its legal status remains grey. Valve has historically been very supportive of community modifications, but unofficial web ports of their commercial intellectual properties operate at Valve's discretion.
Nevertheless, the technical achievements of this port are undeniable. It proves that with WebAssembly, WebGL2 (and in the future, WebGPU), the web browser has evolved from a simple document viewer into a highly capable, near-native runtime for complex 3D applications. For game developers, it highlights a future where distribution friction is completely eliminated: players can jump into a high-fidelity 3D experience with a single click.