A type-safe, high-level WebAssembly.
Wado was born from a practical need: embedding small Wasm modules in JavaScript projects without the binary size explosion that comes with existing Wasm-targeting languages.
Existing solutions bundle their own memory management runtime into every .wasm file, resulting in bloated binaries even for simple tasks. Wado takes a different approach: by leveraging Wasm GC, the garbage collector is provided by the Wasm runtime itself (currently wasmtime; browser support pending Wasm Component Model), keeping your binaries minimal.
The timing matters too. With Wasm Component Model and WASI P3 maturing in 2026, Wado is designed from the ground up for this new era — no legacy baggage, no retrofitting.
#!/usr/bin/env wado run
use { println, Stdout } from "core:cli";
// run() is the entry point of the wasi:cli's Command world
fn run() with Stdout {
println("Hello, world!");
}
Run it:
wado run example/hello.wadoCompile to WebAssembly:
wado compile example/hello.wado # generates example/hello.wasm
wado compile -o example/hello.wasm example/hello.wado # ditto
wado compile --format wasm example/hello.wado # ditto
wado compile --format wat example/hello.wado # generates example/hello.wat with WAT format
wado compile -o example/hello.wat example/hello.wado # ditto- Static typing with generics — strong type system with generic types, functions, and methods. No
anyescape hatch - Rust-like semantics without lifetimes — value semantics, references (
&T,&mut T), and structs withimplblocks, but memory is managed by Wasm GC, so no lifetime annotations needed - Familiar syntax — borrows from Rust (structs,
impl,let/let mut) and JavaScript/TypeScript (template strings with backticks, ES module-styleuse {...} from "..."imports)
Effects map directly to WASI capabilities, making side effects explicit and controllable:
fn download_and_save(url: String, path: String) with Http, FileSystem {
let data = Http::get(url).body;
FileSystem::write(path, data);
}
The with clause tells you exactly what a function can do. This enables:
- Security: Sandbox plugins with only the capabilities you grant
- Testability: Swap real effects with mocks via handlers
- Clarity: No hidden side effects
No macros. The code you read is the code that runs — Wasm in plain sight.
Explicit over implicit. No implicit type conversions, no function overloading, no hidden dependencies. You shouldn't need to jump to other files to understand what a function does.
Strong static typing with no escape hatches like any. This prevents the defensive programming patterns (excessive try-catch, runtime type checks) that tend to creep into dynamically-typed codebases.
Errors are handled explicitly with Result<T, E> instead of unwinding exceptions. This makes control flow predictable and easier to reason about.
By leveraging Wasm GC instead of bundling a runtime, Wado produces compact .wasm files. This is the core motivation behind the language.
Wado is experimental. The core language — syntax, static typing, generics, closures, modules — is implemented and functional.
However:
- WASI P3 is not yet finalized: The spec is at release candidate stage, and runtime support is limited
- Wasm Component Model is not yet supported in browsers
- Wasm stack switching is not yet available in wasmtime
That said, Wado is already usable for its original purpose: embedding lightweight Wasm modules in JS projects where binary size matters.
Thanks to Wasm Stack Switching (not yet available in runtimes), all functions will be "colorless" — no async/await infection:
fn fetch_all() with Http {
let users = Http::get("/users"); // No await needed
let posts = Http::get("/posts"); // Just works
return (users, posts);
}
Built-in reactive state for UI and event-driven applications:
use {observe} from "core:reactive";
let reactive mut count = 0; // Mutable reactive state
let reactive doubled = || count * 2; // Derived value
observe(|| {
println(`Count: {count}, Doubled: {doubled}`);
});
count += 1; // Automatically propagates to `doubled` and triggers observe()
Why built-in instead of a library?
- Compiler optimization: Dependencies are analyzed at compile-time, generating precise Wasm update code with no runtime tracking overhead
- Ergonomics: No wrapper functions like
useState(),ref(), orcreateSignal() - Automatic dependency tracking:
observe()automatically tracks reactive values accessed within the closure—no manual subscription needed - No virtual DOM: Updates compile to direct mutations, not diffing
- Context-aware: In CLI, updates are synchronous; in event-looped environments (browser/GUI), updates may be batched for efficiency
JSX syntax will enable declarative UI descriptions:
fn App() -> Node {
let reactive mut count = 0;
return <div>
<h1>Count: {count}</h1>
<button onclick={|| count += 1}>Increment</button>
</div>;
}
Combined with reactive signals, this will provide a compile-time optimized UI framework without virtual DOM overhead.
As the spec finalizes and runtime support matures, Wado will leverage async streams, futures, and the full capability model.
Wado is developed entirely through agentic coding — AI agents write the code while the human handles design decisions and project management.
This isn't just a curiosity; it shaped the language itself. After a year of intensive agentic coding experience, certain patterns became clear:
- Agents excel at volume but struggle with ambiguity. Implicit behaviors get multiplied across a codebase. Explicit, predictable semantics work better.
- Agents tend toward defensive programming. Without type safety, they pepper code with
hasattrchecks and nestedtry-exceptblocks. Strong types eliminate this need. - Exceptions break agent reasoning. Non-local control flow is hard to predict.
Result<T, E>keeps everything visible.
The result: a language where common agentic coding pitfalls are eliminated by design, not convention.
- Cheatsheet - Quick syntax reference
- Language Specification - Full language reference
- Compiler Implementation - Compiler internals and feature checklist
- Benchmarks - Performance benchmarks vs C and JavaScript, and so on
- Other Documentation - WEP, research notes, TODOs, etc.
Wado is developed entirely through agentic coding — AI agents write all the code while the human handles language design and project management.
This approach requires active management:
- Refactoring guidance: Left unchecked, agents generate case-specific code that only works for immediate tests. Regular intervention steers toward generalizable solutions.
- Code minimization: Agents tend to over-generate logic. Compilers need minimal, general-purpose code — the opposite of what agents naturally produce.
- Periodic refactoring phases: Without intervention, cruft accumulates. We've done one ground-up compiler architecture redesign so far.
AI-guided optimization is a technique where you show generated code to a coding agent and have it identify optimization opportunities. The agent's output is non-deterministic, but the insights can be turned into deterministic compiler rules.
Wado's optimizer is developed using this approach:
Agent finds pattern → Human reviews → Deterministic optimization rule added
Show the generated WAT to an agent and ask it to spot inefficiencies. Review the suggestions, then implement them as permanent optimization passes.
Use the provided Makefile task to set up everything automatically:
make on-task-started # installs mise and all project toolsSee .mise.toml for the list of managed tools.
cargo build
cargo test-
wado compile FILE- Compile Wado source to Wasm/WAT -
wado run FILE- Run Wado source directly using Wasmtime -
wado dump FILE- Dump internal compiler state for debugging -
wado format FILE- Format Wado source code
There are E2E test fixtures in wado-compiler/tests/fixtures/*.wado.
The wado-vscode/ directory contains a VS Code extension for syntax highlighting. It is not published to the marketplace, but you can install it locally for development:
make install-wado-vscode-dev # install extension to ~/.vscode via symlink
make clean-wado-vscode-dev # uninstall it from ~/.vscode
make update-wado-vscode-grammar # regenerate syntax files after changing syntax.rsSee wado-vscode/README.md for more details.
make on-task-done # format, clippy-fix, update-bundled, testCopyright (c) 2026, FUJI Goro (a.k.a. gfx). Some rights reserved.
MIT
See LICENSE for details.