DEV Community

Daniel Budden
Daniel Budden

Posted on

4 2

Running WebAssembly outside of the browser

This is the third article in a series of posts on Rust, WebAssembly and Genetic Algorithms. If you haven't read the first or second articles in this series it's definitely worth going back to them before continuing. In this article I will talk about Wasmtime, a runtime for executing WebAssembly outside of the browser. I'll take the algorithm developed in the first article in this series, build some extra features for improved command line usage, compile to WebAssembly and run the WebAssembly module from the command line with Wasmtime.

The complete code for this post can be found here.

Abstract image of green and white swirls
Photo by Darío Méndez on Unsplash

The first improvement I've made to the Rust code from the first post in this series is to take the algorithm parameters as command line arguments. To enable this I've added the structopt crate, which builds on the popular clap crate, and allows the definition of command line arguments using a struct. To define the CLI arguments a struct is defined and used with a macro and custom derive from structopt.

#[derive(StructOpt)]
#[structopt()]
struct Opt {
    #[structopt(name = "iterations")]
    iterations: usize,
    #[structopt(name = "pop_size")]
    population_size: usize,
    #[structopt(name = "crossover_rate")]
    crossover_rate: f64,
    #[structopt(name = "mutation_rate")]
    mutation_rate: f64,
    #[structopt(name = "survival_rate")]
    survival_rate: f64,
    #[structopt(name = "csv", parse(from_os_str))]
    csv: PathBuf,
}

fn main() {
    let opts = Opt::from_args();
    ...
}

The second change is to parse the list of cities for the travelling salesman problem from a CSV file. The CSV will have two columns, the first being the x co-ordinate and the second being the y co-ordinate for each city. The first row of the CSV file will contain a header with the column names (x and y) and this will allow the rows to be deserialised into the City struct by the csv crate when they are read in.

#[derive(Deserialize)]
pub struct City {
    x: f64,
    y: f64,
}

fn main() {
    ...
    let mut reader = Reader::from_path(opts.csv).unwrap();
    let cities: Vec<City> = reader.deserialize()
        .map(|r| {
            let result: City = r.unwrap();
            result
        })
        .collect();

    ...
}

To get started with Wasmtime you will need to compile it from source. The full details on getting setup can be found here, but for MacOS this involved:

brew install cmake llvm

git clone --recurse-submodules https://github.com/CraneStation/wasmtime.git

cd wasmtime

cargo build

Once Wasmtime is compiled the next step is to ensure the necessary compile target for WebAssembly is available. Wasmtime uses the WebAssembly System Interface (WASI), which provides WebAssembly code with access to operating system features such as the filesystem. Adding the right compile target and compiling the Rust code to WebAssembly is done using:

rustup target add wasm32-wasi

cargo build --target wasm32-wasi --release

And finally running the WebAssembly Genetic Algorithm on the command line with Wasmtime. WebAssembly's security model involves sandboxing, this means that to enable the program to access files from the operating system the Wasmtime runtime needs a list of directories that the program will should be allowed to access. In this case the current directory . is provided so that the WebAssembly module can access the cities.csv file there.

../wasmtime/target/release/wasmtime --dir=. target/wasm32-wasi/release/wasi-genetic.wasm 5000 500 0.4 0.001 0.3 cities.csv

Thanks for reading this series of posts on Rust, WebAssembly and Genetic Algorithm. Any questions, feedback or comments are welcome here or on the repositories listed. The complete code for this post can be found here.

Neon image

Serverless Postgres in 300ms (!)

10 free databases with autoscaling, scale-to-zero, and read replicas. Start building without infrastructure headaches. No credit card needed.

Try for Free →

Top comments (0)

Jetbrains Survey

Calling all developers!

Participate in the Developer Ecosystem Survey 2025 and get the chance to win a MacBook Pro, an iPhone 16, or other exciting prizes. Contribute to our research on the development landscape.

Take the survey

👋 Kindness is contagious

Dive into this insightful write-up, celebrated within the collaborative DEV Community. Developers at any stage are invited to contribute and elevate our shared skills.

A simple "thank you" can boost someone’s spirits—leave your kudos in the comments!

On DEV, exchanging ideas fuels progress and deepens our connections. If this post helped you, a brief note of thanks goes a long way.

Okay