wasm

Installation

Add io.github.edadma:wasm:0.4.0 (and optionally wasm-wasi) to your sbt build, or work from a local checkout for development.

Maven Central

Released artifacts (Scala 3, cross-built on JVM / Scala.js / Scala Native):

libraryDependencies ++= Seq(
  "io.github.edadma" %%% "wasm"      % "0.4.0",
  "io.github.edadma" %%% "wasm-wasi" % "0.4.0",  // optional — only if you want the WASI shim
)

%%% (triple %) is the sbt-crossproject form that picks the right artifact for each platform — drop one % if you’re on a non-cross build. The CLI (wasm-cli) is built from this repo but is not published; it’s a runnable example, not a library.

CoordinateWhat you get
io.github.edadma:wasm:0.4.0The interpreter — Runtime.instantiate, ModuleInstance.
io.github.edadma:wasm-wasi:0.4.0The WASI Preview 1 host shim — depends on wasm.

The wasm artifact has zero external runtime dependencies; the wasm-wasi artifact depends only on wasm.

From source

If you want to build the repo locally — to run the test suite, hack on the interpreter, or use the CLI runner — clone and run:

git clone https://github.com/edadma/wasm.git
cd wasm
sbt test                                              # whole tree, all backends# whole tree, all backends
sbt 'interpJVM/Test/run'                              # 653 interpreter tests, JVM
sbt 'wasiJVM/Test/run'                                # 209 WASI tests, JVM
sbt 'cliJVM/Test/run'                                 # 19 CLI tests

The aggregate sbt test runs the interpreter and WASI suites on JVM, Scala.js (Node 20+), and Scala Native, plus the CLI suite on the JVM. 881 tests total on JVM; the interpreter and WASI also pass on JS and Native.

Linking against a local checkout

If you’re hacking on the interpreter and want a downstream project to pick up your changes without a publishSigned round-trip, point the downstream sbt build at the local source tree:

lazy val wasm = ProjectRef(file("../wasm"), "interpJVM")
lazy val wasi = ProjectRef(file("../wasm"), "wasiJVM")

lazy val myProject = project
  .dependsOn(wasm, wasi)

The same trick works for cliJVM, interpJS, interpNative, etc.

Cross-build matrix

TargetVersionRuntime requirement
Scala3.8.3
JVMJava 17 or newer
Scala.js1.21.0Node.js 20+
Scala Native0.5.11Clang

Verifying the install

Drop this in any @main source file inside the cloned repo, run with sbt 'interpJVM/run', and you should see 120:

import io.github.edadma.wasm.*

@main def smoke(): Unit =
  // The committed `fact.wasm` fixture is a factorial export — fact(5) = 120.
  val bytes = java.nio.file.Files.readAllBytes(
    java.nio.file.Paths.get("interp/shared/src/test/resources/fixtures/fact.wasm")
  )
  Runtime.instantiate(bytes, Seq(EnvModule.default)) match
    case Right(inst) =>
      inst.invoke("fact", Seq(I32(5))) match
        case Right(Seq(I32(v))) => println(v)
        case Right(_)           => println("no result")
        case Left(err)          => println(s"trap: $err")
    case Left(err) => println(s"instantiate failed: $err")

If you see 120, you’re done. Move on to the Quickstart for a tour of the API surface most callers actually use.

Search

Esc
to navigate to open Esc to close