wss is a transpiler from WebAssembly to CSS, plus an HTML/CSS runtime.
The result runs entirely in pure HTML/CSS; optional JavaScript add-ons are available for quality-of-life features.
Several interactive outputs are checked into examples/ and mirrored online:
- Rust toolchain
- A compiler that can emit WebAssembly, such as
clang - A recent Chromium-based browser for running the generated HTML
- Prepare your WebAssembly file:
// source.c
extern int putchar(int c);
extern int getchar();
int _start() {
putchar('H');
putchar('e');
putchar('l');
putchar('l');
putchar('o');
putchar('\n');
return 0;
}Use any WebAssembly-capable compiler. Export _start as the entry point and (optionally) import putchar and getchar for console I/O.
clang \
--target=wasm32 -Os \
-nostdlib \
-mno-simd128 \
-fno-exceptions \
-mno-bulk-memory \
-mno-multivalue \
-Wfloat-conversion \
-Wl,--gc-sections \
-Wl,--no-stack-first \
-Wl,--allow-undefined \
-Wl,-z,stack-size=512 \
-Wl,--compress-relocations \
-Wl,--strip-all \
-Wl,--global-base=4 \
-Wl,--export=_start \
-o a.wasm source.c- Run the transpiler:
cargo run --release -- a.wasm -o a.htmlOptions:
-o, --output <PATH>: output HTML path. Default:a.html--memory-bytes <N>: runtime linear-memory cap in bytes. Default:1024--stack-slots <N>: runtime callstack cap in 16-bit slots. Default:256--js-clock: enable JS-based clock stepping. This is the default.--no-js-clock: disable JS-based clock stepping.--js-coprocessor: enable the JS coprocessor fordiv/remand bitwise builtins. Conflicts with--no-js-clock.--js-clock-debugger: enable the JS debugger popup. Conflicts with--no-js-clock.--max-phys-regs <N>: register-allocation cap, including reservedr0-r3. Default:256
- i32 arithmetic — add, sub, mul, div, rem, and, or, xor, shl, shr, rotl, rotr, clz, ctz, popcnt, eqz
- i32 comparisons — eq, ne, lt, gt, le, ge (signed and unsigned)
- i32 memory — load and store with 8-, 16-, and 32-bit widths (signed and unsigned loads)
- Control flow — block, loop, if/else, br, br_if, br_table, return, unreachable
- Function calls with TCO — call, call_indirect, return_call, return_call_indirect
- Locals and globals — get, set, tee
- Select — typed and untyped select
- i64 arithmetic
- Exception handling — try/catch and related ops
- Floats — f32/f64 and all float ops
- SIMD — v128 and vector ops
- Atomics — all atomic load/store/rmw
- memory.grow — impossible to implement without JS
- GC - No
- Threads - No
This project is inspired by x86CSS.