https://github.com/daxter-army/react-cpp-wasm-app
React + Cpp + WebAssembly Todo Application to learn about WebAssembly. This repo can serve as a good starter example on how to build a C++ and React with WebAssembly.
https://github.com/daxter-army/react-cpp-wasm-app
cpp css-modules emscripten react vite-app wasm
Last synced: 24 days ago
JSON representation
React + Cpp + WebAssembly Todo Application to learn about WebAssembly. This repo can serve as a good starter example on how to build a C++ and React with WebAssembly.
- Host: GitHub
- URL: https://github.com/daxter-army/react-cpp-wasm-app
- Owner: daxter-army
- Created: 2023-09-13T16:20:37.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-12-15T04:53:56.000Z (about 2 years ago)
- Last Synced: 2025-03-15T20:42:11.594Z (10 months ago)
- Topics: cpp, css-modules, emscripten, react, vite-app, wasm
- Language: JavaScript
- Homepage: https://daxter-army.github.io/react-cpp-wasm-app/
- Size: 503 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React + Cpp + WebAssembly (WASM) Todo App

## ๐ก Idea
* So as we all know __WebAssembly__ or __WASM__ is a new type of code that can be run in modern web browsers. We can use Low-Level languages like C/C++, Go, Rust etc, to compile them in binary format, that can be run alongwith JS in the browser. So I was also very much excited with the idea, so here is an implementation from my side, which implements a simple Todo App, using C++ at the back handling all the logic for CRUD regarding managing Todos, and at the front React is being used to communicate with C++ code (Classes and Objects) and displaying UI. **App idea is not something new, it is simple, but I wanted to learn how this technology works, as this was my first WebAssembly app/playground**.
## ๐ Prerequisites
* __NodeJS > 16.x__ (By default, Emscripten uses its own version of NodeJS, but you can change this if you want to, I proceeded with the default version which is downloaded with emscripten. [Visit docs to learn more](https://emscripten.org/docs/getting_started/downloads.html#installation-instructions-using-the-emsdk-recommended))
* __C++ >= 11__ (gcc/g++ version)
* __Emscripten (The tool which converts C++ code to wasm code)__ (Whichever is the latest stable version)
## ๐ Development
### ๐ C++ Logic Implementation
* ```note.cpp```: Contains implementation regarding an individual ```Note```, which hosts to private member variables the following attributes:
| attribute | type | description |
|-------------|--------|-------------|
| description | string | string which describes the todo |
| status | bool | status whether it is completed or not |
* Contains public member functions to implement basic utility functionalities.
* ```notes.cpp```: Contains implementation of ```vector notes```, which acts as an array to hold todos in it. Just like the way we put todos in an array in JS, and then manipulate it. The ```Notes``` class contains the CRUD functionality for altering todos at its side.
* ```main.cpp```: Contains ```main()``` driver code for Notes class, which is not doing much, but acting as an entry point.
### ๐๏ธ C++ & WASM Bundling using Emscripten
* Our main aim is to call the __public member functions__ defined in ```Notes``` class from our JS code.
* __EMSCRIPTEN_BINDINGS__ is used to bind C++ classes, so that they are available to call from JS. You can choose what function to expose or not, and it will also affect your bundle size. More functions will result in increased bundle size.
* ```#define EXTERN extern "C"``` is used to avoid [__Name Mangling__](https://www.ibm.com/docs/en/i/7.5?topic=linkage-name-mangling-c-only).
* Build Command: ```emcc -lembind -o wasm.js main.cpp -s NO_EXIT_RUNTIME=1 -s "EXPORTED_RUNTIME_METHODS=['ccall']"```
1. ```-lembind```: Directs to use EMSCRIPTEN_BINDINGS
2. ```-o ```: Names for the files to be generated by emscripten. No need to put name of all C++ files. They are automatically handled, just put the name os entrypoint file for C++ code.
3. ```-s NO_EXIT_RUNTIME=1```: Tells the C++ code to not exit, as we can call its functions anytime. Otherwise the code would exit and we would get errors.
4. ```"EXPORTED_RUNTIME_METHODS=['ccall']"```: The method that we use to call C++ code, other method is ```cwrap()```.
### ๐ฆบ WASM Integration with React App
* A Module object is attached to the ```window``` object, and therefore we can refer to our wasm module at ```window.Module```
* We can initialise our class's instance like this ```var instance = new windowm.Module.Notes()```.
* Above line will initialize an object of type ```Notes```, which is saved in ```instance``` variable.
* We can call ```Notes -> add("Learn WASM!")``` like this ```instance.add("Learn WASM!")``` here and so on.
* Further ```NotesContext``` and ```WASMContext``` are used in the React App to handle and distribute data among the whole app.
## โ๏ธ Local Development Setup
### ๐ ๏ธ Development Workflow I followed
1. Write C++ code โคต
2. Bundle the code with __Emscripten__ โคต
3. Copy the 2 output files ```/cpp_files/.js```, ```/cpp_files/.wasm``` to ```/wasm``` โคต
4. Adjust the imports in ```index.html``` (If you have changed file names)
* First you can develop C++ code and check that, everyting is working fine with your C++ code, then you can go for building the code with Emscripten.
### ๐ฆ Directory Notes
* All C++ related code is in ```cpp_files```. When done, can use Emscripten to bundle these files.
* You can use compression flags like ```-O0```, ```-O1```, ```-O2```, ```-O3``` with ```emcc``` command to compress and minify your wasm and JS glue files.
* Parent Directory houses the React client code.
* Open terminal at the parent Directory and hit ```npm run dev``` and your code is live at ```http://localhost:5173```.
* hit ```npm run build``` to create production build of React app.
## ๐ Resources
* [Emscripten: Connecting Cpp and JS](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-ccall-cwrap)
* [Compiling a New C/C++ Module to WebAssembly](https://developer.mozilla.org/en-US/docs/WebAssembly/C_to_wasm#creating_html_and_javascript)
* [StackOverflow: Call C++ Classes in Emscripten](https://stackoverflow.com/questions/15865923/interaction-with-c-classes-in-emscripten)