{"id":28238579,"url":"https://github.com/yann39/java-wasm-teavm","last_synced_at":"2026-05-01T21:33:47.857Z","repository":{"id":269117231,"uuid":"778460567","full_name":"Yann39/java-wasm-teavm","owner":"Yann39","description":"Some Java to WebAssembly examples using TeaVM","archived":false,"fork":false,"pushed_at":"2024-09-01T19:25:22.000Z","size":1228,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-03T11:30:42.666Z","etag":null,"topics":["java","maven","teavm","wasm","webassembly"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Yann39.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-27T19:12:14.000Z","updated_at":"2026-02-10T17:22:50.000Z","dependencies_parsed_at":"2024-12-21T04:13:03.221Z","dependency_job_id":"c3f2034e-de19-48f7-ac0e-79f69e1b2589","html_url":"https://github.com/Yann39/java-wasm-teavm","commit_stats":null,"previous_names":["yann39/java-wasm-teavm"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Yann39/java-wasm-teavm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yann39%2Fjava-wasm-teavm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yann39%2Fjava-wasm-teavm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yann39%2Fjava-wasm-teavm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yann39%2Fjava-wasm-teavm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Yann39","download_url":"https://codeload.github.com/Yann39/java-wasm-teavm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Yann39%2Fjava-wasm-teavm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32513730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","maven","teavm","wasm","webassembly"],"created_at":"2025-05-19T01:13:09.213Z","updated_at":"2026-05-01T21:33:47.832Z","avatar_url":"https://github.com/Yann39.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Java WASM TeaVM\n\nExploring **WebAssembly** and testing in **Java** through **TeaVM**.\n\n![Version](https://img.shields.io/badge/Version-0.0.3-2AAB92.svg)\n![Static Badge](https://img.shields.io/badge/Last%20update-20%20Dec%202022-blue)\n\n![Version](https://img.shields.io/badge/JDK-11-red.svg)\n![Version](https://img.shields.io/badge/TeaVM-0.9.2-green.svg)\n\n---\n\n# Table of Contents\n\n* [About the Project](#about-the-project)\n* [What is WebAssembly](#what-is-webassembly-)\n  * [Promise](#promise)\n  * [WASM vs Docker](#wasm-vs-docker)\n  * [Compilers](#compilers)\n  * [Docker \u0026 Wasm](#docker--wasm)\n  * [Performance](#performance)\n  * [Usage](#usage)\n  * [Examples](#examples)\n  * [Conclusion](#conclusion)\n* [Java - TeaVM](#java---teavm)\n  * [Minimal example](#minimal-example) \n  * [Project's examples](#projects-examples)\n  * [Usage](#usage)\n* [License](#license)\n\n# About the Project\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\n        \u003cimg alt=\"Java logo\" src=\"doc/logo-java.svg\" height=\"72\"/\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n        \u003cimg alt=\"WebAssembly logo\" src=\"doc/logo-wasm.svg\" height=\"64\"/\u003e\n    \u003c/td\u003e\n    \u003ctd\u003e\n        \u003cimg alt=\"Maven logo\" src=\"doc/logo-maven.svg\" height=\"42\"/\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\nThis is just to explore a bit about WebAssembly and specially in Java.\n\n# What is WebAssembly ?\n\n- **W3C** standard\n- Presented in June 2015, released in March 2017, **W3C recommendation** since December 2019\n- Binary instruction format (**bytecode**)\n- Executable in a **virtual machine** (wasm runtime)\n- **Portable** (not architecture or microprocessor dependent), x86 / ARM / RISC-V compatible\n- **Secure** (runs in a sandbox, separate from the host runtime)\n- **Compilable** from several languages (currently 40+ languages), C, C++, Rust, Go,\n  and more recently Java, Kotlin, C#, Dart, Swift, Zig, ...\n  and even interpreted languages such as PHP, Python or Ruby via interpreter compilation\n- Executable in a **browser** (compatible with Firefox, Chrome, Safari, Opera, Edge since 2017) via Web APIs\n- Executable on a server or in a **container** via [WASI](https://wasi.dev/)\n  / [WasmEdge](https://github.com/WasmEdge/Wasmedge)\n- **Lightweight** (small binaries), and **performance** close to native (\u003e JavaScript)\n\n## Promise\n\n- Create binaries for the web from any language, executable anywhere\n- Create libraries that can be used across multiple languages\n- Create web applications that can use several languages on the same page\n\n## WASM vs Docker\n\nQuote from Solomon Hykes (co-founder of Docker) :\n\n\u003e If WASM+WASI existed in 2008, we wouldn't have needed to create Docker. That's how important it is. WebAssembly on the\n\u003e server is the future of computing\n\n\u003cdiv style=\"width:600px\"\u003e\n\n![wasm-vs-docker.png](doc/wasm-vs-docker.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://medium.com/@shivraj.jadhav82/webassembly-wasm-docker-vs-wasm-275e317324a1\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\nWASM and Docker can be integrated via [Docker WASM](https://docs.docker.com/desktop/wasm/) (beta)\nand/or [container2wasm](https://github.com/ktock/container2wasm).\n\nLinux/Windows containers depend on the processor architecture and the operating system\n(on Linux, you can only run Linux containers, and on Windows only Windows containers (or Linux, but\nvia a VM through Hyper-V)), this is not the case with WASM containers.\n\n## Compilers\n\nPrograms must be compiled to obtain WebAssembly modules. For interpreted languages,\nthe interpreter is compiled into WebAssembly.\n\n\u003cdiv style=\"width:600px\"\u003e\n\n![wasm-compile.png](doc/wasm-compile.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://wasmlabs.dev/articles/docker-without-containers/\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\n- For C / C++ (every language that uses **LLVM**) : `emscripten`\n\n  ```shell\n  sudo apt install emscripten\n  emcc hello.c -o hello.html\n  ```\n\n- For Rust : `wasm-pack`\n\n  ```shell\n  cargo install wasm-pack\n  wasm-pack build --target web\n  ```\n\n- For Flutter (Dart) : via `js_interop` package and flag `--wasm` (on browsers that support `WasmGC`)\n\n  ```shell\n  flutter build web --wasm\n  ```\n\n- For Go : Native since Go 1.11 via environment variables\n\n  ```shell\n  GOOS=js GOARCH=wasm go build -o main.wasm\n  ```\n\n- For Java : JVM bytecode to WebAssembly\n  via [Bytecoder](https://mirkosertic.github.io/Bytecoder/), [TeaVM](https://www.teavm.org/)\n  or [Cheerpj](https://cheerpj.com/)\n\n  ```shell\n  java -jar bytecoder-cli.jar -classpath=. -mainclass=Hello -builddirectory=. -backend=wasm \n  ```\n\n## Docker \u0026 Wasm\n\n### Wasm workloads\n\n- Currently, you need to activate the feature in Docker Desktop\n\n- Then specify the runtime and platform at runtime :\n\n  ```shell\n  docker run --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm mywasm\n  ```\n\n### Image to WASM via [container2wasm](https://github.com/ktock/container2wasm) :\n\nConverting image to WASM, i.e. :\n\n```shell\nc2w ubuntu:22.04 /tmp/wasm/out.wasm\n```\n\nRunning in a browser through Apache, i.e. :\n\n```shell\nc2w ubuntu:22.04 /tmp/out-js2/htdocs/out.wasm\ncp -R ./examples/wasi-browser/* /tmp/out-js2/ \u0026\u0026 chmod 755 /tmp/out-js2/htdocs\ndocker run --rm -p 8080:80 \\\n         -v \"/tmp/out-js2/htdocs:/usr/local/apache2/htdocs/:ro\" \\\n         -v \"/tmp/out-js2/xterm-pty.conf:/usr/local/apache2/conf/extra/xterm-pty.conf:ro\" \\\n         --entrypoint=/bin/sh httpd -c 'echo \"Include conf/extra/xterm-pty.conf\" \u003e\u003e /usr/local/apache2/conf/httpd.conf \u0026\u0026 httpd-foreground'\n```\n\n## Performance\n\n\u003cdiv style=\"width:500px\"\u003e\n\n![wasm-performance.png](doc/wasm-performance.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://www.youtube.com/watch?v=MFruf7aqcbE\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\n## Usage\n\n_Statistics 2023_\n\n\u003cdiv style=\"width:500px\"\u003e\n\n![wasm-usage.png](doc/wasm-usage.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://web.developpez.com/actu/349740\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\n\u003cdiv style=\"width:500px\"\u003e\n\n![wasm-desirability.png](doc/wasm-desirability.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://web.developpez.com/actu/349740\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\nAlso used in various blockchains (Cosmos, Polkadot, MultiversX, Near Protocol) !\n\n## Examples\n\nSome WASM applications that run in the browser :\n\n- C++ :\n\n  - Google Earth : https://earth.google.com/web\n  - Kunky Karts (jeu) : https://www.funkykarts.rocks/demo.html\n  - Quake \u0026 Quake 2 : https://quake.m-h.org.uk/ \u0026 https://quake2.m-h.org.uk/\n\n- PHP :\n\n  - Wordpress : https://wordpress.wasmlabs.dev or https://playground.wordpress.net/\n  - Drupal \u0026 more : https://seanmorris.github.io/php-wasm\n\n- Kotlin :\n\n  - JetSnack : https://zal.im/wasm/jetsnack/\n\n- Go :\n\n  - Chess (compilé via TinyGo) : https://marianogappa.github.io/cheesse-examples/)\n\n- Rust :\n\n  - Python interpreter : https://rustpython.github.io/demo/\n\n- Linux :\n\n  - Linux simple https://bellard.org/jslinux/vm.html?url=alpine-x86.cfg\u0026mem=192\n  - Linux simple with networking and C : https://ja.nsommer.dk/articles/linux-and-tiny-c-compiler-in-the-browser-part-one.html\n  - Linux with Python sur RISC V : https://ktock.github.io/container2wasm-demo/riscv64-python.html\n  - Linux with networking through Tailscale (and Python) : https://webvm.io/\n  - Linux via CheerpX (with Python, Ruby, NodeJs, C++) : https://repl.leaningtech.com/?python3=\n\n- Other tools :\n\n  - JupyterLite : https://jupyterlite.github.io/demo\n\nList of projects made with WebAssembly : https://madewithwebassembly.com/\n\n## Conclusion\n\n- Despite the promise of speed, the tools I've tried are pretty slow\n- Most features are experimental, almost exclusively in preview or alpha versions\n- The standard is incomplete and continues to evolve (rapidly though)\n- Difficult to debug and profile (lack of tools)\n\nPotential uses :\n\n- Training, easily give users a ready-to-use environment (i.e. WordPress, Linux, Python, etc.)\n- Testing new architectures, new distributions, etc.\n- Libraries (shared across different systems / languages), even if TeaVM is not designed for this currently\n\n# Java - TeaVM\n\n**TeamVM** is a **Java bytecode compiler** that emits JavaScript and/or WebAssembly to be executed in the browser.\n\n- It does not require source code, only compiled files (not like GWT, for example)\n- it also supports Kotlin and Scala\n\n\u003cdiv style=\"width:500px\"\u003e\n\n![wasm-teavm.png](doc/wasm-teavm.png)\n\n\u003cdiv style=\"text-align:center; font-size: 10px; font-style: italic; margin-top:-15px;\"\u003e\n\nsource : https://www.youtube.com/watch?v=MFruf7aqcbE\n\n\u003c/div\u003e\n\n\u003c/div\u003e\n\n## Minimal example\n\nHere is a minimal example to compile a Java function into WebAssembly and then use it in JavaScript within an HTML file.\n\n1. Create a new **Maven** project. Here's a basic _pom.xml_ configuration that includes the `teavm-maven-plugin` to compile Java to WebAssembly :\n\n    ```xml\n    \u003cproject xmlns=\"http://maven.apache.org/POM/4.0.0\"\n             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n             xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\"\u003e\n        \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n        \u003cgroupId\u003ecom.example\u003c/groupId\u003e\n        \u003cartifactId\u003eteavm-wasm-example\u003c/artifactId\u003e\n        \u003cversion\u003e1.0-SNAPSHOT\u003c/version\u003e\n    \n        \u003cdependencies\u003e\n            \u003cdependency\u003e\n                \u003cgroupId\u003eorg.teavm\u003c/groupId\u003e\n                \u003cartifactId\u003eteavm-classlib\u003c/artifactId\u003e\n                \u003cversion\u003e${teavm.version}\u003c/version\u003e\n                \u003cscope\u003eprovided\u003c/scope\u003e\n            \u003c/dependency\u003e\n        \u003c/dependencies\u003e\n    \n        \u003cbuild\u003e\n            \u003cplugins\u003e\n                \u003cplugin\u003e\n                    \u003cgroupId\u003eorg.teavm\u003c/groupId\u003e\n                    \u003cartifactId\u003eteavm-maven-plugin\u003c/artifactId\u003e\n                    \u003cversion\u003e0.9.2\u003c/version\u003e\n                    \u003cexecutions\u003e\n                        \u003cexecution\u003e\n                            \u003cgoals\u003e\n                                \u003cgoal\u003ecompile\u003c/goal\u003e\n                            \u003c/goals\u003e\n                            \u003cconfiguration\u003e\n                                \u003cmainClass\u003ecom.example.HelloWasm\u003c/mainClass\u003e\n                                \u003ctargetDirectory\u003e${project.basedir}/src/main/webapp/wasm\u003c/targetDirectory\u003e\n                                \u003ctargetFileName\u003ehelloworld\u003c/targetFileName\u003e\n                                \u003ctargetType\u003eWEBASSEMBLY\u003c/targetType\u003e\n                                \u003coptimizationLevel\u003eFULL\u003c/optimizationLevel\u003e\n                            \u003c/configuration\u003e\n                        \u003c/execution\u003e\n                    \u003c/executions\u003e\n                \u003c/plugin\u003e\n            \u003c/plugins\u003e\n        \u003c/build\u003e\n    \u003c/project\u003e\n    ```\n\n2. Create a minimal Java class with a simple static method that you want to compile to WebAssembly and export it :\n\n    ```java\n    package com.example;\n    \n    import org.teavm.interop.Export;\n    \n    public class HelloWasm {\n    \n        public static void main(String[] args) {}\n    \n        @Export(name = \"add\")\n        public static int add(int a, int b) {\n            return a + b;\n        }\n    \n    }\n    ```\n   \n    As stated in the docs, TeaVM is not designed to port libraries, so we should always have a \"main\" method, to serve as an entry point.\n\n3. Create the HTML and JavaScript to Use WASM :\n\n    ```html\n    \u003c!DOCTYPE html\u003e\n    \u003chtml lang=\"en\"\u003e\n    \u003chead\u003e\n        \u003cmeta charset=\"UTF-8\"\u003e\n        \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n        \u003ctitle\u003eTeaVM WASM Example\u003c/title\u003e\n        \u003cscript src=\"wasm/helloworld.wasm-runtime.js\"\u003e\u003c/script\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003ch1\u003eTeaVM WASM Example\u003c/h1\u003e\n        \u003cp id=\"output\"\u003e\u003c/p\u003e\n        \u003cscript\u003e\n            async function loadWasm() {\n                const teavmInstance = await TeaVM.wasm.load('wasm/sumwasm.wasm');\n                const result = teavmInstance.instance.exports.add(10, 20);\n                document.getElementById('output').textContent = 'Result : ' + result;\n            }\n            loadWasm();\n        \u003c/script\u003e\n    \u003c/body\u003e\n    \u003c/html\u003e\n    ```\n   \n4. Build the project :\n\n    ```bash\n    mvn clean package\n    ```\n    \n    After building, the WebAssembly file _helloworld.wasm_ should be located in _src/main/webapp/wasm/_.\n    \n    It should also have generated a _helloworld.wasm-runtime.js_ file, designed to handle the instantiation and management of the WebAssembly module.\n    The script sets up necessary functions and imports, making it easier to work with the WebAssembly module (it is loaded in our HTML file).\n\n5. Run the HTML file :\n\n    Make sure to copy the HTML file in the proper location (above the _wasm_ directory containing the .wasm and .js files)\n    then just run it with your preferred browser, it should display `Result : 30`.\n\n## Project's examples\n\nThis project contains 3 examples :\n- `HelloJs` : compiled to Javascript, to demonstrate how to generate a JavaScript file from Java, that can be used from HTML\n- `SumWasm` : compiled to WASM, to demonstrate how to export a Java function to WebAssembly module and call it from Javascript\n- `HelloWasm` : compiled to WASM, to demonstrate how to export a Java function to WebAssembly module and call it from Javascript,\n   and also how to import a javascript function that can be redefined in JavaScript (2-way interaction)\n\n\u003e [!NOTE]\n\u003e The `HelloWasm` example does not work as expected (will display \"undefined\" instead of the hello world string),\n\u003e this is because WebAssembly itself does not natively support string types (or any other complex data structures),\n\u003e so managing strings between Java, WebAssembly and JavaScript involves some additional steps.\n\u003e I think it's a bit of a tinkering, so I haven't gone any further for the moment, I prefer to wait for improvements to the framework so that this can be managed more easily.\n\nConfiguration is done via the Maven plugin `teavm-maven-plugin`, see [TeaVM](https://www.teavm.org/docs/tooling/maven.html).\n\nThe plugin defines an execution for each of the example, you can at the configuration in the _pom.xml_.\n\nBasically, for WASM examples, TeaVM compiles the Java class into a WASM binary,\nthe JavaScript loads this WASM file, instantiate it, and call the exported methods.\nThe result is displayed on the webpage.\n\nTeaVM automatically creates corresponding JS files containing the necessary JavaScript functions that the WebAssembly module requires,\nit also contains helpers to handle the instantiation and management of the WebAssembly module,\nthis is why we load the corresponding JavaScript runtime file in each HTML file.\n\nIn case you don't want to generate / include these files, you will need to define the imports manually, for example :\n\n```javascript\n// define the imports required by TeaVM, including the logInt, logString, and currentTimeMillis functions\nconst imports = {\n    teavm: {\n        // provide the current time in milliseconds\n        currentTimeMillis: () =\u003e Date.now(),\n\n        // log strings passed from WASM to the browser's console\n        logString: (address) =\u003e {\n            const memory = instance.exports.memory;\n            const bytes = new Uint8Array(memory.buffer, address);\n            let str = '';\n            for (let i = 0; i \u003c bytes.length \u0026\u0026 bytes[i] !== 0; i++) {\n                str += String.fromCharCode(bytes[i]);\n            }\n            console.log(str);\n        },\n\n        // log integers passed from WASM to the browser's console\n        logInt: (value) =\u003e {\n            console.log(value);\n        }\n        \n        ...\n    }\n};\n\n// instantiate the WebAssembly module with the imports\nconst result = await WebAssembly.instantiate(bytes, imports);\n```\n\n## Usage\n\nSimply package the project to generate the WASM and JS binaries :\n\n```bash\nmvn clean package\n```\n\nThe TeaVM Maven plugin will generate the files in the _target/webapp_ directory.\n\nThen copy the HTML files into the _target/webapp/_ folder and launch them in your preferred browser.\n\n# License\n\n[General Public License (GPL) v3](https://www.gnu.org/licenses/gpl-3.0.en.html)\n\nThis program is free software: you can redistribute it and/or modify it under the terms of the GNU\nGeneral Public License as published by the Free Software Foundation, either version 3 of the\nLicense, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\neven the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\nGeneral Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program. If not,\nsee \u003chttp://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyann39%2Fjava-wasm-teavm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyann39%2Fjava-wasm-teavm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyann39%2Fjava-wasm-teavm/lists"}