examples/jspi-opfs/index.html
JSPI lets plain (non-async) Rust functions await JS Promises by suspending the WASM fiber — without blocking the event loop. This example applies that to the browser's Origin Private File System (OPFS), whose entire API surface is Promise-based.
WebAssembly.Suspending``navigator.storage.getDirectoryWASM module
wasm-bindgen-futures | JSPI | |
|---|---|---|
| Rust call style | async fn | ordinary fn |
| Awaiting Promises | .await | block_on_promise() |
| Event loop blocked? | no | no |
| Needs async call chain? | yes | no |
Four OPFS operations — each requires multiple Promise awaits — are exposed as plain Rust functions via #[wasm_bindgen(jspi)]:
// ── write a file ─────────────────────────────────────#[wasm\_bindgen(jspi)]pub fnopfs\_write(path: String, content: String) {letroot =opfs\_root();// suspends onceletfh = block_on_promise(&root.get\_file\_handle\_with\_options(...));letwr = block_on_promise(&fh.create\_writable());// suspends againblock_on_promise(&wr.write\_with\_str(&content));
block_on_promise(&WritableStream::close(&wr));
}// ── read a file ──────────────────────────────────────#[wasm\_bindgen(jspi)]pub fnopfs\_read(path: String) -> String {letfh: FileSystemFileHandle = block_on_promise(&opfs\_root()
.get\_file\_handle(&path)).dyn\_into()...;letfile: File = block_on_promise(&fh.get\_file()).dyn\_into()...;
block_on_promise(&Blob::text(&file)).as\_string()...
}
The generated JS glue wraps each export with WebAssembly.promising, so JavaScript callers simply await the result as usual.
File path (OPFS key)
ContentHello from plain Rust via JSPI + OPFS! Second line here 🦀
WriteReadHas?Delete▶ Run all
clear