{"id":27296130,"url":"https://github.com/corendos/wasm-hot-loading","last_synced_at":"2026-05-10T03:50:53.889Z","repository":{"id":190667237,"uuid":"655788322","full_name":"Corendos/wasm-hot-loading","owner":"Corendos","description":"WASM Module hotloading in native apps","archived":false,"fork":false,"pushed_at":"2023-12-17T15:28:16.000Z","size":11962,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-12-17T16:31:03.494Z","etag":null,"topics":["cpp","native","wasm","zig"],"latest_commit_sha":null,"homepage":"https://medium.com/@corentin.godeau37/efficient-and-secure-module-hot-loading-on-native-platforms-6f1826d8c858","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Corendos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-06-19T15:43:54.000Z","updated_at":"2023-12-17T15:45:52.000Z","dependencies_parsed_at":"2023-12-17T16:39:59.608Z","dependency_job_id":null,"html_url":"https://github.com/Corendos/wasm-hot-loading","commit_stats":null,"previous_names":["corendos/wasm-hot-loading"],"tags_count":0,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corendos%2Fwasm-hot-loading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corendos%2Fwasm-hot-loading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corendos%2Fwasm-hot-loading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Corendos%2Fwasm-hot-loading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Corendos","download_url":"https://codeload.github.com/Corendos/wasm-hot-loading/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248494636,"owners_count":21113473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","native","wasm","zig"],"created_at":"2025-04-11T23:30:15.579Z","updated_at":"2026-05-10T03:50:53.678Z","avatar_url":"https://github.com/Corendos.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wasm Hot-loading sample\n\nThis directory contains a proof-of-concept of Wasm module hot-loading in native apps.\n\nIt's composed of three main parts:\n* The sample core\n* The sample Wasm module\n* The server serving the Wasm module\n\n## The Sample Core\n\nThe sample core is responsible to wrap the Wasm Module into a C++ usable interface. The code for that is under the `whl` namespace and in the `whl/` sub-folder.\n\nIt also contains convenience wrapper for the Wasm runtime we use, [wasm3](https://github.com/wasm3/wasm3). It simply wraps the C interface in C++ classes.\n\n## The Wasm module\n\nThe Wasm module is available in the `wasm/zig/` sub-folder. It's written in the [Zig](https://ziglang.org/) programming language because of its first-class support of Wasm.\n\n## The server\n\nIn the `server/` subfolder, there is a very basic python server used to serve the Wasm module compiled from Zig sources. More details in the associated [README](./server/README.md).\n\n# How to build\n\n## Cloning the repository\n\nFirst, when cloning this repository, don't forget to get the submodules as well. If you're first cloning the repository you can do so with:\n\n```bash\ngit clone git@github.com:Corendos/wasm-hot-loading.git --recursive\n```\n\nIf you forgot, you can always fetch the submodules afterwards with:\n\n```bash\ngit submodules update --init --recursive\n```\n\n## Dependencies\n\nThe required dependencies are:\n* [CMake](https://cmake.org/download/) - Any version \u003e= 3.19 will work and you'll get an error message otherwise.\n* [Zig](https://ziglang.org/download/) - Zig is a pre-1.0 language so it's moving fast. This sample was tested with version `0.12.0-dev.1744+f29302f91`.\n* [Go](https://go.dev/doc/install) - Go language (This is a transitive dependency of BoringlSSL).\n\n## Building the Sample Core\n\nYou can build the sample CLI with:\n\n```bash\n# Configure the project\ncmake -Bbuild -DCMAKE_BUILD_TYPE=Debug .\n# Build the sample\ncmake --build build --target sample --parallel\n```\n\nAlternatively, you can build all the targets with:\n\n```bash\ncmake --build build --target all --parallel\n```\n\n## Running the sample\n\nThe sample is a CLI executable and includes an usage string. Here is its content:\n\n```\nWasm hot-loading sample\nUsage: ./build/bin/sample [OPTIONS]\n\nOptions:\n  -h,--help                   Print this help message and exit\n  --module-url TEXT           The URL of the Wasm module to load\n  --key TEXT:FILE REQUIRED    The Public key to use to verify Wasm module integrity\n  --stack-size UINT:SIZE [b, kb(=1024b), ...]\n                              The size of the stack that will be allocated for the module instance\n```\n\n## Building the sample Wasm module\n\nTo build the sample Wasm module, you simply have to run the following command:\n\n```bash\n# Go to the module source directory\ncd wasm/zig\n# Build it, optionally compiling it in ReleaseSmall mode\nzig build -Drelease=\u003ctrue|false\u003e\n```\n\nThis will produce the `zig-out/bin/module.wasm` artifact that will ultimately be served by the Python Flask application.\n\n## Running the local server\n\nIf not already done, initialize a virtualenv locally and install the dependencies using the `requirements.txt` file. Then, activate this virtual environment. Alternatively, if you know what you are doing, you can install the dependencies in the global Python interpreter environment.\n\nTo run the Python Flask server, first update the `server/config.json` file if needed and then run the Flask app with:\n\n```bash\ncd server\nflask --app server run\n```\n\n## Step-by-Step tutorial\n\nIf you want to see results quickly, here is a fully detailed process of everything required to test this sample:\n\n```bash\n# Assuming your current directory is the root of the repository\n\n# Create a Python3 virtual environment\npython3 -m venv venv\n# Activate this environment\nsource ./venv/bin/activate\n# Install Python deps\npip install -r requirements.txt\n\n# Go the the Wasm sample module directory\ncd wasm/zig/\n# Build the module\nzig build -Drelease=true\n# Go back to repository root\ncd ../..\n\n# Configure C++ project\ncmake -Bbuild -DCMAKE_BUILD_TYPE=Debug .\n# Build C++ sample\ncmake --build build --target sample --parallel\n\n# /!\\ In another terminal /!\\\ncd server\n# Start Flask app with default config\nflask --app server run\n# /!\\ In antoher terminal /!\\\n\n\n# Launch the sample with Flask URL and default public key\n./build/bin/sample --module-url http://127.0.0.1:5000/wasm/module.wasm --key certs/pubkey.pem\n```\n\nThis should run the sample and print some message originating from the Wasm module.\n\n# How it works\n\nFirst of all, we need to define the `Scheduler` notion. A `Scheduler` is the main building-block of this sample design. It has two roles:\n* Executing tasks once at a specific time or repeatedly at specific intervals.\n* Handling messages\n\nThe `Scheduler` type is a template class with two templates, the type of message it can handle and the type of message handler it can notify. Generally speaking, the message handle is also a template class using the message type, so we are closer to having only one template type.\n\nA `Scheduler` executes scheduled tasks and message handler on a unique thread, ensuring a mono-threaded context. This is a strong guarantee as it enable us to avoid any synchronization primitives in the part of the code we know are running in the context of a Scheduler.\n\nIn this sample, we have two separate `Scheduler`. The \"global\" `Scheduler` whose role is to handle all the \"default\" messages and the \"Sample\" `Scheduler` whose role is to handle all the messages and tasks that will ultimately be handled/run in Wasm code.\n\nThe `whl::GlobalMessageType` and `whl::GlobalMessage` types represent the messages that the \"Global\" `Scheduler` can handle and the `whl::SampleMessageType` and `whl::SampleMessage` types represent the messages that the \"Sample\" `Scheduler` can handle. They have their counterparts declared in the Zig code as well and they need to stay in sync.\n\nIf you take a look at the code (more specifically the [`whl/src/whl/sample_module.cpp`](./whl/src/whl/sample_module.cpp) file), you can see that the `SampleModule` class handles all the interaction with the Wasm Module and is handling messages sent to the \"Sample\" `Scheduler`. It's also exposing the \"Global\" `Scheduler` through a `Sender` interface so that the Wasm Module can send messages to it.\n\nFinally, all of this logic is wrapped in the `whl::WasmHotLoading` class (defined in [`platform/bridge/cpp/wasm_hot_loading.cpp`](./platform/bridge/cpp/wasm_hot_loading.cpp)), so that's easy to use from any platform (more details on that later).\n\nOn top of that, a default Wasm module is embedded inside the built binary. It's generated from the Zig code in the `wasm/zig` folder and declared as an array literal in the `whl/include/whl/default_sample_module.hpp` file. To generate this file, I wrote a small Python script that can be found in `scripts/convert.py`. It's documented and pretty straightforward.\n\nThis let us fallback to a known and tested module implementation if needed.\n\n# Running it on and Android device\n\nSuch a sample would not be complete if there wasn't something out of the ordinary. To show that this solution is multi-platform, I integrated it inside an Android app.\n\nIt relies on a fork of [djinni](https://djinni.xlcpp.dev/) to generate bindings for Java and Objective-C. In the previous section, I talked about the `whl::WasmHotLoading` class. In practice, this class is an interface exposed in Java and Objective-C with an implementation in C++. This way, we can use the class seamlessly in a CLI app or Android app.\n\nThis interface is defined using Djinni's Interface Definition Language ([IDL](https://djinni.xlcpp.dev/djinni-generator/idl/)) in the `djinni/whl.djinni` file. This file contains some comment to help you understand how it's supposed to be used.\n\nIf you want to update this schema, you will need to regenerate the bindings using the `scripts/run_djinni.sh` script. Otherwise, the default version is committed with this repository and should work out-of-the box.\n\nTo see the application in action, simply open the Android project in the `platform/android` folder and build it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorendos%2Fwasm-hot-loading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcorendos%2Fwasm-hot-loading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcorendos%2Fwasm-hot-loading/lists"}