Water; wasmCloud; TinyWeb
(For those questioning my sanity/spelling, today’s Drop focuses on WebAssembly — i.e., “WASM” — resources.)
This paragraph has nothing to do with today’s Drop theme, but — for RStats readers — I took an initial stab at adding Flexoki {ggplot2} scales and general palettes to dev-mode {hrbrthemes} (https://github.com/hrbrmstr/hrbrthemes). I need to round out some corners, and get brave enough to run CRAN checks (it’s been a minute since I’ve interacted with anything CRAN). It should be up on CRAN by February.

This paragraph also has nothing to do with today’s Drop, but I saw that Docker Desktop on macOS is still having issues, and wanted to offer some assistance/advice. I featured OrbStack around this time last year, and strongly suggest macOS folk switch to it. I get nothing for promoting the use of OrbStack (and pay the subscription fee to support it, and use the debug shell). It’s fully Docker compatible and has an extremely well-crafted UX.
We’ve covered many WASM topics before, but just in case “WASM” is a new term for anyone, it’s a binary instruction format that runs code with near-native performance. You can write WebAssembly by hand, or compile a wide range of languages to WASM, making the resultant binary runnable on any supported platform without modification. WebR, Pyodide, DuckDB WASM, etc. are all examples of why this tech is useful/important. Today’s Drop has three neat, recent WASM finds.
TL;DR
(This is an AI-generated summary of today’s Drop using Ollama + llama 3.2 and a custom prompt.)
- A web-based fluid simulation called “Water” demonstrates complex physics calculations using WebAssembly SIMD support and Material Point Method for realistic fluid behavior (https://oimo.io/works/water/)
- wasmCloud platform enables distributed systems by packaging applications as portable WASM modules that can run anywhere, using capability providers to connect with various services (https://wasmcloud.com/)
- TinyWeb is a new minimal Rust framework for building client-side web applications that takes an unconventional approach to WebAssembly integration by directly handling primitive type transmission (https://github.com/LiveDuo/tinyweb)
Water

“Water” (GH) is a web-based fluid simulation that is a great example of how modern browsers can handle complex physics calculations in real-time. The project uses the Material Point Method (MPM) combined with Affine Particle-in-Cell (APIC) (direct PDF link) transfer to create realistic fluid behavior.
In case you have not hit the link, yet, the visualization creates realistic water-like effects by varying particle size based on local density. It also colors particles according to aeration level, and uses depth sorting for better visual quality. A nice touch is how it generates foam/bubble effects in areas of high acceleration.
I tossed this into today’s Drop mix since I did not realize WebAssembly had leveled up to include SIMD support, and was fairly impressed by the fact that the demo (you hopefully already clicked/tapped on) was 100% SIMD WASM (though you can switch to plain JS).
To track individual particles moving through space, this simulation takes uses a “Lagrangian view”. Picture following a leaf floating down a stream and recording its exact path. This perspective provides sufficient detail about how individual bits of material move and interact.
The “Eulerian view” is more like setting up a series of fixed cameras to watch that same stream. Instead of following individual particles, it measures what happens at specific fixed points in space. This approach makes it much easier to solve complex physics equations since we’re working with a nice, orderly grid. (Wikipedia entry on both views.)
The Water demo combines these approaches by letting particles carry around physical properties like mass and velocity as they move through space, but temporarily maps those properties onto a fixed background grid when it’s time to solve the physics equations. Think of it like having your particles drop off their information at fixed checkpoints, letting the math happen there, and then picking up their updated states before continuing their journey.
This approach excels at handling situations where materials undergo large deformations or when different types of materials interact. The grid makes it easy to detect collisions and compute gradients, while the particles ensure we don’t lose track of material properties even during extreme deformations. When the simulation needs to solve equations, it uses the grid, but all the important physical information stays with the particles as they move.
It also uses custom interpolation functions to smoothly transfer information back and forth between the particles and the grid; and, the WASM speed comes from the use of SIMD vectors, enabling it to handle four particles simultaneously.
Play around with it! You can bend the fluid to your will via mouse/taps and swish it around (it works with your device’s accelerometer). You can also see how performant your device is by messing with the quality settings, and toggle between WASM and JavaScript.
wasmCloud

(This is a very brief intro to wasmCloud, as it has a bonkers number of capabilities. It could have had its own Drop, but I only had cycles to make sure it worked easily enough to recommend folks poke at it.)
wasmCloud (GH) builds on the capabilities of WASM to create distributed systems that work across different environments. It separates application code from infrastructure details; so — instead of tying applications to specific frameworks or systems — wasmCloud packages them as portable WASM modules. These modules can run anywhere, be it Kubernetes, regular servers, or IoT/”edge” devices. Each module acts as an “actor” that performs specific tasks.
The platform uses “capability providers” to connect with services like databases and message queues. Applications specify what capabilities they need (like sending messages) without worrying about specific implementations. The platform handles the connections automatically, so you can switch providers without changing your code.
This design makes scaling easier, as the actors are independent units that can spread across clusters without manual configuration of load balancers or network settings. wasmCloud manages this through its “lattice” architecture — a network that connects all wasmCloud nodes and handles workload distribution.
Setting up wasmCloud is straightforward. It runs as a single executable and uses a “Neural Autonomic Transport System” (NATS) (GH) — a messaging system — to connect nodes. You can run it locally for development or on Kubernetes for production.
I followed the intro guide and had it up and running locally super quick. I’ll get an edge deployment of it on one of my servers later in the year and get a walkthrough going of more than the toy examples they provide.
TinyWeb

(Def skip this if you have no desire/intention to mess with Rust.)
TinyWeb is a fairly new Rust framework for building client-side web applications 100% in Rust.
It has a minimal footprint (~800 LoC) mostly due to the developers taking an unconventional approach to WebAssembly integration. Rather than using wasm-bindgen (like most Rust web frameworks), it directly handles primitive type transmission between Rust and JavaScript, only fetching specific properties when needed.
The framework consists of just three core components:
- An HTML entry point
- A static JavaScript file
- A WebAssembly binary compiled from Rust code
The system bootstraps through a DOMContentLoaded event listener that triggers the main Rust function once the page loads. This function typically handles initial DOM rendering and event listener registration. Communication with browser APIs happens through an internal __invoke function that bridges Rust and JavaScript. The callback system stores Rust functions in a CALLBACK_HANDLERS collection, executing them when corresponding events trigger.
TinyWeb implements a signals-based reactivity system similar to modern JavaScript frameworks:
let signal_count = Signal::new(0);
El::new("button").text("add").on("click", move
{
let count = signal_count.get() + 1;
signal_count.set(count);
});
It also provides a built-in router that supports client-side navigation:
let pages = &[Page::new("/page1", page_component())];
ROUTER.with(|s| { *s.borrow_mut() = Router::new("body", pages); });
And, TinyWeb includes a runtime for handling asynchronous operations:
Runtime::block_on(async move {
Runtime::promise("window.setTimeout({},{})",
move |c| vec![c.into(), 1_000.into()]).await;
Js::invoke("alert('timer')");
});
The project is still very experimental, but takes a super-interesting approach to minimalist Rust web development.
FIN
Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:
- 🐘 Mastodon via
@dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev - 🦋 Bluesky via
https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy
Also, refer to:
to see how to access a regularly updated database of all the Drops with extracted links, and full-text search capability. ☮️
Leave a comment