If, like me, you are intrigued by WASM and you don't how to step in, then give an eye to Coi
Coil let's you code you web app in a declarative way like React and compile it through C++ to WASM with the help of WebCC
I have installed the toolchain in WSL and the compilation is very fast.
There is also a VSCode extention :
import "../components/Button.coi";
component AudioPlayer {
mut Audio audio;
mut bool playing = false;
mut float currentTime = 0;
mut float duration = 0;
mut float progress = 0;
mut int volume = 80;
mount {
// Replace with your own audio file URL
audio = Audio.createAudio(
"https://cdn.pixabay.com/audio/2025/06/23/audio_e6a00ad257.mp3"
);
audio.setVolume(0.8);
System.log("test" + duration);
}
tick(float dt) {
if (playing) {
currentTime = audio.getCurrentTime();
duration = audio.getDuration();
if (duration > 0) {
progress = (currentTime / duration) * 100;
}
}
}
def togglePlay(): void {
if (playing) {
audio.pause();
playing = false;
} else {
audio.play();
playing = true;
duration = audio.getDuration();
}
}
def volumeUp(): void {
if (volume < 100) {
volume = volume + 10;
if (volume > 100) {
volume = 100;
}
float vol = volume / 100.0;
audio.setVolume(vol);
}
}
def volumeDown(): void {
if (volume > 0) {
volume = volume - 10;
if (volume < 0) {
volume = 0;
}
float vol = volume / 100.0;
audio.setVolume(vol);
}
}
style {
.audio-player {
display: flex;
flex-direction: column;
gap: 20px;
padding: 40px;
background: #fff;
border: 1px solid #eee;
border-radius: 12px;
width: 280px;
}
.label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
color: #999;
text-align: center;
}
.track-info {
text-align: center;
}
.track-title {
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
margin-bottom: 4px;
}
.track-artist {
font-size: 13px;
color: #666;
}
.album-art {
width: 160px;
height: 160px;
background: linear-gradient(135deg, #9477ff 0%, #6b5ce7 100%);
border-radius: 12px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
font-size: 60px;
box-shadow: 0 4px 15px rgba(148, 119, 255, 0.3);
}
.progress-container {
display: flex;
flex-direction: column;
gap: 8px;
}
.progress-bar {
width: 100%;
height: 6px;
background: #eee;
border-radius: 3px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #9477ff, #b19fff);
border-radius: 3px;
transition: width 0.1s linear;
}
.time-info {
display: flex;
justify-content: space-between;
font-size: 12px;
color: #666;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
}
.play-btn {
width: 56px;
height: 56px;
border-radius: 50%;
background: #9477ff;
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: #fff;
transition: all 0.2s ease;
box-shadow: 0 4px 15px rgba(148, 119, 255, 0.4);
}
.play-btn:hover {
transform: scale(1.05);
background: #a388ff;
}
.volume-container {
display: flex;
align-items: center;
gap: 8px;
}
.volume-icon {
font-size: 16px;
color: #666;
}
.volume-bar {
flex: 1;
height: 6px;
background: #eee;
border-radius: 3px;
overflow: hidden;
}
.volume-fill {
height: 100%;
background: #9477ff;
border-radius: 3px;
transition: width 0.1s ease;
}
.volume-btn {
width: 28px;
height: 28px;
border-radius: 50%;
background: #f5f5f5;
border: 1px solid #eee;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
transition: all 0.2s ease;
}
.volume-btn:hover {
background: #9477ff;
color: #fff;
border-color: #9477ff;
}
.volume-text {
font-size: 12px;
color: #666;
width: 35px;
text-align: right;
}
}
view {
<div class="audio-player">
<div class="label">Audio Player</div>
<div class="album-art">🎵</div>
<div class="track-info">
<div class="track-title">Coify</div>
<div class="track-artist">Demo Track</div>
</div>
<div class="progress-container">
<div class="progress-bar">
<div
class="progress-fill"
style="width: {progress}%;"
></div>
</div>
<div class="time-info">
<span>{currentTime}s</span>
<span>{duration}s</span>
</div>
</div>
<div class="controls">
<button class="play-btn" onclick={togglePlay}>
<if playing>
<span>⏸</span>
<else>
<span>▶</span>
</else>
</if>
</button>
</div>
<div class="volume-container">
<span class="volume-icon">🔊</span>
<button class="volume-btn" onclick={volumeDown}>−</button>
<div class="volume-bar">
<div
class="volume-fill"
style="width: {volume}%;"
></div>
</div>
<button class="volume-btn" onclick={volumeUp}>+</button>
<span class="volume-text">{volume}%</span>
</div>
</div>
}
}
app { root = AudioPlayer; }
Then compile the code (very fast:
python:~/coi/example/src/demos$ coi AudioPlayer.coi --out ./dist
Processing /home/python/coi/example/src/demos/AudioPlayer.coi...
Processing /home/python/coi/example/src/components/Button.coi...
All files processed. Total components: 2
Generated ./dist/app.css
Running: webcc /tmp/coi_build/app.cc --out /home/python/coi/example/src/demos/./dist --cache-dir /tmp/coi_build/webcc_cache --template /tmp/coi_build/index.template.html
[WebCC] Loading definitions from compiled-in schema...
[WebCC] Loaded 130 commands and 17 events.
[WebCC] Scanning source files for features...
-> Found get_body (dom), embedding JS support.
-> Found create_element (dom), embedding JS support.
-> Found set_attribute (dom), embedding JS support.
-> Found append_child (dom), embedding JS support.
-> Found remove_element (dom), embedding JS support.
-> Found set_inner_text (dom), embedding JS support.
-> Found add_click_listener (dom), embedding JS support.
-> Found log (system), embedding JS support.
-> Found set_main_loop (system), embedding JS support.
-> Found open_url (system), embedding JS support.
-> Found create_audio (audio), embedding JS support.
-> Found play (audio), embedding JS support.
-> Found pause (audio), embedding JS support.
-> Found set_volume (audio), embedding JS support.
-> Found get_current_time (audio), embedding JS support.
-> Found get_duration (audio), embedding JS support.
[WebCC] Generated /home/python/coi/example/src/demos/./dist/app.js
[WebCC] Using template: /tmp/coi_build/index.template.html
[WebCC] Generated /home/python/coi/example/src/demos/./dist/index.html
[WebCC] Compiling...
[CC] /tmp/coi_build/app.cc
[CC] /home/python/webcc/src/core/command_buffer.cc
[CC] /home/python/webcc/src/core/event_buffer.cc
[CC] /home/python/webcc/src/core/scratch_buffer.cc
[CC] /home/python/webcc/src/core/libc.cc
[WebCC] Linking...
[WebCC] Success! Run 'python3 -m http.server' in /home/python/coi/example/src/demos/./dist to view.
Here is the output, magic!!! :
python@:~/coi/example/src/demos/dist$ ls -rtl
total 64
-rw-r--r-- 1 python python 4460 Jan 11 14:05 app.css
-rw-r--r-- 1 python python 298 Jan 11 14:05 index.html
-rw-r--r-- 1 python python 13789 Jan 11 14:05 app.js
-rwxr-xr-x 1 python python 34063 Jan 11 14:05 app.wasm
Note the size of the wasm file.
Click below to experiment the demo:

Top comments (0)