Loading repository data…
Loading repository data…
io-eric / repository
A lightweight C++ toolchain and framework for WebAssembly.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
WebCC is a lightweight, zero-dependency C++ toolchain and framework for building WebAssembly applications.
It provides a direct, high-performance bridge between C++ and HTML5 APIs (DOM, Canvas, WebGL, WebGPU, Audio, ...).
vector, string, iostream, etc.) designed to be a fraction of the size of standard implementations.WEBCC_JS): drop raw JavaScript inline for APIs the schema doesn't cover yet. Still tree-shaken via the import table, with zero cost when unused..webcc_cache for faster rebuilds.WebCC is designed to be lightweight. In a Canvas 2D benchmark rendering 10,000 rectangles:
See the benchmark/ directory for details and to run it yourself.
Full documentation is available in the docs/ directory.
Here is a complete example of creating a Canvas, handling mouse input, and running a loop:
#include "webcc/canvas.h"
#include "webcc/dom.h"
#include "webcc/system.h"
#include "webcc/input.h"
// Global handles
webcc::Canvas canvas;
webcc::CanvasContext2D ctx;
int mouse_x = 400;
int mouse_y = 300;
// Main loop function called every frame
void update(float time_ms) {
// Poll events
webcc::Event e;
while (webcc::poll_event(e)) {
if (auto event = e.as<webcc::input::MouseMoveEvent>()) {
mouse_x = event->x;
mouse_y = event->y;
}
}
// Clear background (Blue)
webcc::canvas::set_fill_style(ctx, 52, 152, 219);
webcc::canvas::fill_rect(ctx, 0, 0, 800, 600);
// Draw circle at mouse position (Yellow)
webcc::canvas::begin_path(ctx);
webcc::canvas::arc(ctx, mouse_x, mouse_y, 50, 0, 6.28318f);
webcc::canvas::set_fill_style(ctx, 241, 196, 15);
webcc::canvas::fill(ctx);
// Draw text
webcc::canvas::set_font(ctx, "30px Arial");
webcc::canvas::set_fill_style(ctx, 255, 255, 255);
webcc::canvas::fill_text(ctx, "Move your mouse!", 280, 500);
// Flush commands to JS
webcc::flush();
}
int main() {
// Setup DOM
webcc::handle body = webcc::dom::get_body();
canvas = webcc::canvas::create_canvas("game-canvas", 800, 600);
webcc::dom::append_child(body, canvas);
// Get Context
ctx = webcc::canvas::get_context_2d(canvas);
// Initialize mouse input on the canvas
webcc::input::init_mouse(canvas);
// Start the main loop
webcc::system::set_main_loop(update);
// Flush commands to JS
webcc::flush();
return 0;
}
Need a browser API the schema doesn't cover yet? Define a function with a raw-JavaScript body using WEBCC_JS, then call it like any other C++ function. Its whole source is compiled into a wasm import name, so it's tree-shaken like everything else and costs nothing when unused.
#include "webcc/system.h" // any webcc header makes WEBCC_JS available
// WEBCC_JS(return_type, name, (params), { body }): params are passed by name
WEBCC_JS(void, set_title, (const char* title), {
document.title = title;
});
WEBCC_JS(int, js_add, (int a, int b), {
return a + b;
});
int main() {
set_title("Hello from C++");
int sum = js_add(2, 3);
(void)sum;
return 0;
}
Parameters cross by name: numeric types arrive as JS numbers and const char* is auto-decoded to a JS string. Calls run synchronously and flush() first (so they see preceding batched commands), which also means each one crosses the JS boundary; on hot paths prefer a real schema command, which batches. See docs/api/inline_js.md for the full reference.
Build the toolchain (first time only):
Bootstraps the webcc compiler. This script compiles a bootstrap version of the tool, generates the API headers from the schema, and then compiles the final webcc binary with the schema embedded.
./build.sh
The script will also offer to install webcc to your system PATH.
Compile your app:
webcc main.cc
(Use ./webcc if you chose not to install it to your PATH).
Run:
python3 -m http.server
Open http://localhost:8000.
Clone the repository:
git clone https://github.com/io-eric/webcc.git
cd webcc
Prerequisites:
clang++ version 16 or later (required for full C++20 support).
sudo apt install clang-16brew install llvmsudo dnf install clangThe webcc tool is your primary interface for the framework.
Generates the C++ header files in include/webcc/ from schema.def.
Note: This is used internally by
build.sh. If you modifyschema.def, you should run./build.shto rebuild the tool so that the embedded schema matches your changes.
./webcc --headers [schema.def]
Compiles your C++ source files into app.wasm, and generates the optimized app.js and index.html.
Use the --out <dir> flag to specify the output directory (defaults to the current directory).
Use the --cache-dir <dir> flag to specify the cache directory (defaults to .webcc_cache in the source directory).
Use the --template <path> or -t <path> flag to specify a custom HTML template file.
./webcc main.cc [other_sources.cc ...] [--out dist] [--cache-dir .cache] [--template index.template.html]
WebCC supports custom HTML templates for your application. Create a file named index.template.html in your project directory or output directory:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
{{script}}
</body>
</html>
WebCC will automatically inject the <script src="app.js"></script> tag where you place the {{script}} placeholder. If no placeholder is found, the script tag is inserted before </body>.
Template search order (first match wins):
index.template.html in the current working directoryindex.template.html in the output directoryCheck the examples/ directory for complete demos.
webcc_canvas)Interactive 2D graphics with mouse tracking.
webcc_webgl)A rotating 3D cube using raw WebGL calls.
webcc_webgl_waves)Animated wave terrain using WebGL shaders.
webcc_webgpu)A triangle rendered using the WebGPU API.
webcc_dom)Creating and styling HTML elements from C++.
schema.def following the file format and run ./build.sh to regenerate the toolchain.RET:int32), register DOM/audio/image objects in the elements map when appropriate, and ensure your JS implementation is robust (checks for missing handles, etc.).Yes, but prefer the schema. Declaring a command in schema.def gives you a typed, batched, reusable C++ function, always the better option on hot paths. For the gaps, WEBCC_JS is the escape hatch: a C++ function with a raw-JavaScript body (like Emscripten's EM_JS, but built the WebCC way so it's tree-shaken and dispatched through the ordinary wasm import table, no runtime machinery). See Inline JavaScript for the full reference.
The long game is still to grow the schema until you rarely reach for this.
Depends on the project, honestly.
It's growing over time, so the gap keeps shrinking. But for now: the smaller and fresher the project, the better the fit.
webcc/dom.h: DOM manipulation (create, append, remove, attributes).webcc/canvas.h: HTML5 Canvas 2D context.webcc/webgl.h: WebGL context.webcc/wgpu.h: WebGPU context.webcc/audio.h: Audio playback and control.webcc/input.h: Mouse and keyboard input.webcc/system.h: System utilities.webcc/websocket.h: WebSocket communication.webcc/storage.h: Local storage.webcc/image.h: Image loading.