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