Lab · Playground
C and C++ in the browser
Real Clang, compiled to WebAssembly, building and running C and C++ programs entirely inside your browser.
These playgrounds compile with a full Clang/LLVM toolchain that itself runs as WebAssembly (YoWASP Clang). Press Run and your code is compiled to a WebAssembly program, linked against the WASI C library, and executed in a Web Worker. Nothing is sent to a server.
The first run downloads the compiler — about 50 MB — so give it a moment; the browser caches it for every later run and page. Programs can read standard input: press stdin, type some text, then Run.
#include <stdio.h>
int main(void) {
const char *shades = " .:-=+*#%@";
for (int y = -12; y <= 12; y++) {
for (int x = -39; x <= 20; x++) {
double cr = x / 20.0, ci = y / 10.0, zr = 0, zi = 0;
int i = 0;
while (i < 50 && zr * zr + zi * zi < 4) {
double t = zr * zr - zi * zi + cr;
zi = 2 * zr * zi + ci;
zr = t;
i++;
}
putchar(shades[i == 50 ? 9 : i % 9]);
}
putchar('\n');
}
return 0;
}
wc: press stdin, paste some text, and run#include <ctype.h>
#include <stdio.h>
int main(void) {
long lines = 0, words = 0, chars = 0;
int c, in_word = 0;
while ((c = getchar()) != EOF) {
chars++;
if (c == '\n') lines++;
if (isspace(c)) in_word = 0;
else if (!in_word) { in_word = 1; words++; }
}
if (chars == 0) {
puts("Standard input is empty — press stdin, type something, and run again.");
return 0;
}
printf("%ld lines, %ld words, %ld characters\n", lines, words, chars);
return 0;
}
#include <algorithm>
#include <iostream>
#include <map>
#include <numeric>
#include <string>
#include <vector>
int main() {
std::vector<std::string> words{"wasm", "clang", "browser", "llvm", "wasi", "compile", "link", "run"};
std::ranges::sort(words, [](const auto& a, const auto& b) {
return a.size() != b.size() ? a.size() < b.size() : a < b;
});
for (const auto& w : words) std::cout << w << ' ';
std::cout << '\n';
std::map<std::size_t, int> by_length;
for (const auto& w : words) by_length[w.size()]++;
for (const auto& [len, n] : by_length) std::cout << len << " letters: " << n << '\n';
auto total = std::accumulate(words.begin(), words.end(), std::size_t{0},
[](std::size_t t, const auto& w) { return t + w.size(); });
std::cout << "total letters: " << total << '\n';
}
#include <stdint.h>
#include <stdio.h>
#include <string.h>
int main(void) {
// WebAssembly has a flat, bounds-checked linear memory, but C inside it does not:
// writing past an array silently scribbles over whatever is next in memory.
struct { char name[8]; uint32_t balance; } account = { "chris", 100 };
printf("before: %s has %u\n", account.name, account.balance);
strcpy(account.name, "christopher"); /* 12 bytes into an 8-byte array */
printf("after: %s has %u\n", account.name, account.balance);
return 0;
}
How it works
-
The page starts a Web Worker and loads Clang and LLD (LLVM’s linker), both built for WebAssembly, plus the WASI system headers and libraries.
-
Clang compiles your file to a
wasm32-wasiexecutable in an in-memory file system. -
The worker runs that executable with a small WASI shim (browser_wasi_shim) that connects standard input, output, and error to the page.
Stop terminates the worker, so even for (;;); can be interrupted. Threads, sockets, and
files on your disk are not available: WASI programs only see what the page gives them.