Skip to content
explodingcameraPublic

About

A tiny WebAssembly runtime written in safe Rust

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

597 stars

Watchers

7 watching

Forks

tinywasm

Documentation Build Crates.io Crates.io

Why tinywasm?

  • Tiny: Small by design, while still passing the full WebAssembly 3.0 core test suite.
  • Portable: Runs anywhere Rust can target, supports no_std, has minimal dependencies1
  • Safe: Written entirely in safe Rust2.

Installation

[dependencies]
tinywasm = "0.12.0-beta.0"

Usage

use tinywasm::{ModuleInstance, Store};

// Load a module from bytes
let wasm = include_bytes!("../examples/wasm/add.wasm");
let module = tinywasm::parse_bytes(wasm)?;

// Create a new store
let mut store = Store::default();

// Instantiate the module
let instance = ModuleInstance::instantiate(&mut store, &module, None)?;

// Call an exported function with typed parameters
let func = instance.func::<(i32, i32), i32>(&store, "add")?;
let result = func.call(&mut store, (1, 2))?;

assert_eq!(result, 3);

See the examples directory and documentation for more information.

Cargo Features

  • full: Enables archive, debug, parallel-parser, parser, state, and validate. Enabled by default.
  • std: Enables parsing from files and streams, shared memory handles, and blocking atomic wait/notify across stores. Enabled by default.
  • nightly: Enables nightly-only optimizations (if the compiler supports them). Enabled by default.
  • simd-intrinsics: Enables architecture-specific SIMD implementations where available, using unsafe internally. Enabled by default.
  • parser: Enables tinywasm-parser and top-level parse helpers. Enabled by default.
  • validate: Enables WebAssembly validation while parsing. Enabled by default and configurable through ParserOptions.
  • parallel-parser: Parallelizes function parsing when std is enabled. Enabled by default.
  • archive: Enables serialization and deserialization of the internal twasm format. Enabled by default.
  • state: Adds store-owned host state for access from host callbacks. Enabled by default.
  • debug: Derives Debug for runtime types. Enabled by default.
  • send: Makes stores and store-local handles movable across threads.
  • portable-atomic: Supports targets without native atomic compare-and-swap.
  • canonicalize-nans: Uses a canonical NaN for normalized NaN results.
  • guest-debug: Exposes module-internal by-index inspection APIs (*_by_index).
  • log: Enables integration with the log crate.

Use Engine and engine::Config for non-default fuel accounting, stack sizing, or GC collection thresholds. A configured ResourceLimiter can allow, reject, or trap memory and table allocation or growth requests, and GC object allocations.

Precompiled Modules

TinyWasm can serialize a parsed module to its version-specific .twasm format. Loading an archive skips WebAssembly parsing, validation, and optimization.

Applications that only load .twasm can remove the parser and validator from their binary by only enabling the archive feature. Depending on the target and release profile, this can produce binaries smaller than 300 KB.

Untrusted Input

WebAssembly validation is enabled by default through the validate feature. Keep this feature enabled and leave ParserOptions::validation enabled for modules from untrusted sources. Without validation, parsing can produce modules that violate runtime assumptions and may panic during instantiation or execution.

Validation does not limit parsing or execution resources. Hosts that run untrusted code should also configure parser::ParseLimits, stack and ResourceLimiter limits, and fuel-budgeted execution as needed. The default fuel policy counts interpreter steps. Applications can check their own deadlines between calls to resume_with_fuel.

Use parser::ParserOptions::new().with_checkpoint_interval(4096) to tune straight-line budget-check spacing before parsing. The default is 1,024 emitted interpreter instructions, with up to three extra for pending fusion. Larger intervals trade responsiveness for lower checkpoint overhead. Taken loop backedges are checked independently, and synthetic checkpoints consume no fuel.

Loading .twasm checks the archive header and encoding but does not run WebAssembly validation or verify TinyWasm's runtime invariants. Load archives only from trusted sources. For untrusted input, parse a WebAssembly binary with validation enabled.

WebAssembly Proposal Support

TinyWasm generally implements non-JavaScript core proposals at phase 4 or later, with some proposals implemented earlier. The table shows current support and known exceptions.

Proposal Status tinywasm Version
Import/Export of Mutable Globals 🟒 0.2.0
Multi-value 🟒 0.2.0
Non-trapping Float-to-int Conversions 🟒 0.2.0
Sign-extension Operators 🟒 0.2.0
Bulk Memory Operations 🟒 0.4.0
Reference Types 🟒 0.7.0
Fixed-width SIMD 🟒 0.9.0
Tail Calls 🟒 0.9.0
Extended Constant Expressions 🟒 0.9.0
Multiple Memories 🟒 0.8.0
Relaxed SIMD 🟒 0.9.0
Custom Annotation Syntax 🟒 0.8.0
Memory64 🟒 0.9.0
Wide Arithmetic 🟒 0.9.0
Custom Page Sizes 🟒 0.9.0
Typed Function References 🟒 0.11.0
Garbage Collection 🟒 0.11.0
Exception Handling 🟒 0.11.0
Compact Import Section 🟒 0.11.0
Threads3 🟒 0.12.0-beta.0

Legend
πŸŒ‘ -- not available
🚧 -- in development/partially supported
🟒 -- fully supported

Benchmarks

Tinywasm includes a small benchmark suite at crates/bench that runs a set of WebAssembly modules and measures execution time. For comparisons with other runtimes, check out the great wasmi-benchmarks repository.

See Also

If you're looking for a WebAssembly runtime with JIT compilation, better performance or other advanced features, check out these other runtimes:

  • wasmi - efficient and versatile WebAssembly interpreter for embedded systems
  • wasm3 - a fast WebAssembly interpreter written in C
  • wazero - a zero-dependency WebAssembly interpreter written in Go
  • wasmer - a fast and secure WebAssembly runtime written in Rust
  • wasmtime - a fast and secure WebAssembly runtime written in Rust

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in tinywasm by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Footnotes

  1. WebAssembly parsing and validation use wasmparser, and .twasm archives use postcard. ↩

  2. The simd-intrinsics feature uses unsafe internally for selected architecture-specific SIMD implementations. ↩

  3. Shared memory and blocking atomic wait/notify require std. ↩

About

A tiny WebAssembly runtime written in safe Rust

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

597 stars

Watchers

7 watching

Forks

Releases

Used by

Contributors

Languages