Version 2.5.0
twr-wasm is a simple, lightweight and easy to use library for building C/C++ WebAssembly code directly with clang. Run C/C++ code in a web browser. Legacy code, libraries, full applications, or single functions can be integrated with JavaScript and TypeScript. twr-wam solves some common use cases with less work than the more feature rich emscripten.
Key Features:
- build
.wasmmodules using C/C++ using clang directly (no wrapper) - from JavaScript load
.wasmmodules, call C/C++ functions, and access wasm memory - comprehensive console support for
stdin,stdio, andstderr.- in C/C++, print and get characters to/from
<div>tags in your HTML page - in C/C++, print and get characters to/from a
<canvas>based "terminal" - localization support, UTF-8, and windows-1252 support
- in C/C++, print and get characters to/from
- from JavaScript, use
class twrWasmModuleAsyncto:- integrate a C/C++ Read-Eval-Print Loop (REPL) with JavaScript
- integrate a C/C++ CLI or Shell with JavaScript
- In JavaScript
awaiton blocking/synchronous C/C++ functions.
- 2D drawing API for C/C++ compatible with JavaScript Canvas
- audio playback APIs for C/C++
- create your own C/C++ APIs using TypeScript by extending
class twrLibrary - standard C library optimized for WebAssembly
- libc++ built for WebAssembly
- comprehensive examples and documentation
- TypeScript and JavaScript support
| Name | View Live Link | Source Link |
|---|---|---|
| Bouncing Balls (C++) | View bouncing balls | Source for balls |
| Maze Gen/Solve (Win32 C Port) | View live maze | Source for maze |
Input/Output with <div> | View square demo | Source |
I/O to terminal with <canvas> | View demo | Source |
CLI using libc++ and <canvas>) | View console | Source |
The full documentation can be found here
npm install twr-wasm.
For details see https://twiddlingbits.dev/docsite/gettingstarted/installation/
Here is the simplest twr-wasm example.
C code:
#include <stdio.h> void hello() { printf("hello world\n"); } index.html:
<head> <title>Hello World</title> </head> <body> <div id="twr_iodiv"></div> <script type="module"> import {twrWasmModule} from "twr-wasm"; const mod = new twrWasmModule(); await mod.loadWasm("./helloworld.wasm"); await mod.callC(["hello"]); </script> </body> I/O can be directed to or from a <div> or a <canvas> tag. Here is a simple example using a <div> for stdio input and output.
#include <stdio.h> #include <stdlib.h> #include "twr-crt.h" void stdio_div() { char inbuf[64]; char *r; int i; printf("Square Calculator\n"); while (1) { printf("Enter an integer: "); r=twr_mbgets(inbuf); // r is NULL if esc entered. Otherwise r == inbuf if (r) { i=atoi(inbuf); printf("%d squared is %d\n\n",i,i*i); } else { printf("\n"); } } } With an index.html like the following. This time we are using twrWasmModuleAsync which integrates blocking C code into Javascript. twrWasmModuleAsync can also be used to receive key input from a <div> or <canvas> tag.
<body> <div id="stdioDiv" tabindex="0" style="color: DarkGreen; background-color: LightGray; font-size: 18px;font-family: Arial, sans-serif;" > Loading... <br> </div> <script type="module"> import {twrWasmModuleAsync, twrConsoleDiv} from "twr-wasm"; const con = new twrConsoleDiv(document.getElementById("stdioDiv")); const amod = new twrWasmModuleAsync({stdio: con}); // remove 'Loading...' document.getElementById("stdioDiv").innerHTML ="<br>"; // send key events to twrConsoleDiv document.getElementById("stdioDiv").addEventListener("keydown",(ev)=>{con.keyDown(ev)}); await amod.loadWasm("./divcon.wasm"); await amod.callC(["stdio_div"]); </script> </body> The full documentation can be found here