Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wasmerio/wasmer-go
πΉπΈοΈ WebAssembly runtime for Go
https://github.com/wasmerio/wasmer-go
golang golang-library rust wasm webassembly
Last synced: 5 days ago
JSON representation
πΉπΈοΈ WebAssembly runtime for Go
- Host: GitHub
- URL: https://github.com/wasmerio/wasmer-go
- Owner: wasmerio
- License: mit
- Created: 2019-05-01T13:21:28.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-05-24T18:32:30.000Z (8 months ago)
- Last Synced: 2024-12-31T07:08:10.495Z (12 days ago)
- Topics: golang, golang-library, rust, wasm, webassembly
- Language: Go
- Homepage: https://pkg.go.dev/github.com/wasmerio/wasmer-go
- Size: 117 MB
- Stars: 2,847
- Watchers: 49
- Forks: 162
- Open Issues: 78
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ccamel - wasmerio/wasmer-go - πΉπΈοΈ WebAssembly runtime for Go (Go)
README
A complete and mature WebAssembly runtime for Go based on
[Wasmer](https://github.com/wasmerio/wasmer).Features
* **Easy to use**: The `wasmer` API mimics the standard WebAssembly API,
* **Fast**: `wasmer` executes the WebAssembly modules as fast as
possible, close to **native speed**,
* **Safe**: All calls to WebAssembly will be fast, but more
importantly, completely safe and sandboxed.
**Documentation**: [browse the detailed API
documentation](https://pkg.go.dev/github.com/wasmerio/wasmer-go/wasmer)
full of examples.**Examples** as tutorials: [browse the `examples/`
directory](https://github.com/wasmerio/wasmer-go/tree/master/examples),
it's the best place for a complete introduction!# Install
To install the library, follow the classical:
```sh
$ go get github.com/wasmerio/wasmer-go/wasmer
```And you're ready to get fun!
## Supported platforms
This library embeds the Wasmer runtime compiled as shared library
objects, and so uses [`cgo`](https://golang.org/cmd/cgo/) to consume
it. A set of precompiled shared library objects are provided. Thus
this library works (and is tested) on the following platforms:
Platform
Architecture
Triple
Status
Linux
amd64
x86_64-unknown-linux-gnu
β
aarch64
aarch64-unknown-linux-gnu
β
Darwin
amd64
x86_64-apple-darwin
β
aarch64
aarch64-apple-darwin
β³
Windows
amd64
x86_64-pc-windows-msvc
β³
What to do if your platform is missing?
Up to now, there is no script to automate that process. [We are
working on it](https://github.com/wasmerio/wasmer-go/issues/191).Here are the steps to do that manually:
```sh
$ # Build the new Wasmer C API shared object library.
$ cargo build --release
$
$ # Configure cgo.
$ export CGO_CFLAGS="-I$(pwd)/wasmer/packaged/include/"
$ export CGO_LDFLAGS="-Wl,-rpath,$(pwd)/target/release/ -L$(pwd)/target/release/ -lwasmer_go"
$
$ # Run the tests.
$ just test -tags custom_wasmer_runtime
```# Examples
We highly recommend to read the
[`examples/`](https://github.com/wasmerio/wasmer-go/tree/master/examples)
directory, which contains a sequence of examples/tutorials. It's the
best place to learn by reading examples.But for the most eager of you, there is a quick toy program in
`examples/appendices/simple.go`, written in Rust:```rust
#[no_mangle]
pub extern "C" fn sum(x: i32, y: i32) -> i32 {
x + y
}
```A compiled WebAssembly binary is included in
[`examples/appendices/simple.wasm`]((https://github.com/wasmerio/wasmer-go/blob/master/examples/appendices/simple.wasm)).Then, we can execute it in Go:
```go
package mainimport (
"fmt"
"os"
wasmer "github.com/wasmerio/wasmer-go/wasmer"
)func main() {
wasmBytes, _ := os.ReadFile("simple.wasm")engine := wasmer.NewEngine()
store := wasmer.NewStore(engine)// Compiles the module
module, _ := wasmer.NewModule(store, wasmBytes)// Instantiates the module
importObject := wasmer.NewImportObject()
instance, _ := wasmer.NewInstance(module, importObject)// Gets the `sum` exported function from the WebAssembly instance.
sum, _ := instance.Exports.GetFunction("sum")// Calls that exported function with Go standard values. The WebAssembly
// types are inferred and values are casted automatically.
result, _ := sum(5, 37)fmt.Println(result) // 42!
}
```And then, finally, enjoy by running:
```sh
$ cd examples/appendices/
$ go run simple.go
42
```# Testing
Run the tests with the following command:
```sh
$ just test
```# What is WebAssembly?
Quoting [the WebAssembly site](https://webassembly.org/):
> WebAssembly (abbreviated Wasm) is a binary instruction format for a
> stack-based virtual machine. Wasm is designed as a portable target
> for compilation of high-level languages like C/C++/Rust, enabling
> deployment on the web for client and server applications.About speed:
> WebAssembly aims to execute at native speed by taking advantage of
> [common hardware
> capabilities](https://webassembly.org/docs/portability/#assumptions-for-efficient-execution)
> available on a wide range of platforms.About safety:
> WebAssembly describes a memory-safe, sandboxed [execution
> environment](https://webassembly.org/docs/semantics/#linear-memory) [β¦].# License
The entire project is under the MIT License. Please read [the
`LICENSE` file][license].[license]: https://github.com/wasmerio/wasmer/blob/master/LICENSE
# FAQ
## How to run Go programs compiled to WebAssembly modules with `wasmer-go`?
Let's start by emphasing that `wasmer-go` is a WebAssembly runtime. It
allows to _run_ WebAssembly inside Go. It's not a tool to _compile_ a
Go program into WebAssembly. Nonetheless, many people are reporting
issues when compiling Go programs to WebAssembly, and then trying to
run them with `wasmer-go` (or in another hosts, like
[Python](https://github.com/wasmerio/wasmer-python),
[C](https://github.com/wasmerio/wasmer/tree/master/lib/c-api),
[PHP](https://github.com/wasmerio/wasmer-php),
[Ruby](https://github.com/wasmerio/wasmer-ruby),
[Rust](https://github.com/wasmerio/wasmer)β¦).The major problem is that, whilst the Go compiler supports
WebAssembly, [it does not support
WASI](https://github.com/golang/go/issues/31105) (WebAssembly System
Interface). It generates an ABI that is deeply tied to JavaScript, and
one needs to use the `wasm_exec.js` file provided by the Go toolchain,
which doesn't work outside a JavaScript host.Fortunately, there are two solutions to this problem:
1. Use [TinyGo](https://tinygo.org) to compile your Go program to
WebAssembly with the `-target wasi` option, e.g.:
```sh
$ tinygo build -o module.wasm -target wasi .
```
The generated WebAssembly module will be portable across all
WebAssembly runtimes that support WASI.2. Use the Go compiler with adapters. Let's see how to compile:
```sh
$ GOOS=js GOARCH=wasm go build -o module.wasm .
```
(the `GOOS=js` is the sign that JavaScript is targeted, not a surprise).
Then pick one adapter (they are written by the community):
* [`mattn/gowasmer`](https://github.com/mattn/gowasmer/),
* [`go-wasm-adapter/go-wasm`](https://github.com/go-wasm-adapter/go-wasm/),and follow their documentation.
We highly recommend the first solution (with TinyGo) if it works for
you as the WebAssembly module will be portable across all WebAssembly
runtimes. It's not a hacky solution based on adapters; it's the right
way to⦠go.