-
Notifications
You must be signed in to change notification settings - Fork 70
docs: add native Go (Go 1.21) WASI documentation #284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
hydai
merged 5 commits into
WasmEdge:main
from
aaradhychinche-alt:docs/add-native-go-wasi
Jan 21, 2026
+164
−1
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
7130bd4
docs: add native Go (Go 1.21) WASI documentation
aaradhychinche-alt d8af2da
docs: add native Go WASI hello world and host function examples
aaradhychinche-alt e1f7789
docs: link TinyGo hello world to native Go WASI docs
aaradhychinche-alt 993625e
docs: clarify meaning of binary size in Go WASI comparison
aaradhychinche-alt 7235425
docs: remove unsupported binary size comparison
aaradhychinche-alt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,157 @@ | ||
| --- | ||
| sidebar_position: 2 | ||
| --- | ||
|
|
||
| # Native Go with WASI (Go 1.21+) | ||
|
|
||
| Starting with Go 1.21, the Go toolchain natively supports compiling applications to the WebAssembly System Interface (WASI). This enables developers to build WebAssembly applications using the standard Go compiler and run them on WASI-compliant runtimes such as WasmEdge. | ||
|
|
||
| This page describes how to develop and run WASI-based applications using native Go with WasmEdge. It also highlights key differences compared to using TinyGo, which has historically been the primary way to run Go applications on WebAssembly. | ||
|
|
||
| Native Go support is particularly useful for developers who require functionality that is not fully available in the TinyGo standard library, such as more complete language features or integration with existing Go codebases. | ||
|
|
||
|
|
||
| ## TinyGo vs Native Go | ||
|
|
||
| There are currently two ways to develop Go applications for WasmEdge: using TinyGo or using the native Go compiler with WASI support introduced in Go 1.21. Each approach has different trade-offs. | ||
|
|
||
| | Aspect | TinyGo | Native Go (Go 1.21+) | | ||
| |------|--------|----------------------| | ||
| | Compiler | TinyGo (LLVM-based) | Standard Go compiler | | ||
| | Standard library | Partial | More complete | | ||
| | WASI support | Mature | Introduced in Go 1.21 | | ||
| | Networking | Not available by default | Not available by default (WASI limitation) | | ||
| | Typical use cases | Small, resource-constrained workloads | Existing Go codebases, richer language features | | ||
|
|
||
| TinyGo has historically been the primary way to run Go applications on WebAssembly and remains a good choice for lightweight workloads. Native Go with WASI support enables developers to reuse more existing Go code and tooling, but it is still subject to the limitations of the WASI environment. | ||
|
|
||
|
|
||
| ## Hello World example | ||
|
|
||
| The following example demonstrates a minimal Go application compiled to WASI and executed using WasmEdge. | ||
|
|
||
| ### hello.go | ||
|
|
||
| ```go | ||
| package main | ||
|
|
||
| import "fmt" | ||
|
|
||
| func main() { | ||
| fmt.Println("Hello, world") | ||
| } | ||
| ``` | ||
|
|
||
| ### Build | ||
|
|
||
| ```bash | ||
| # initialize a module (optional, but recommended) | ||
| go mod init hello | ||
| # build a WASI-compatible WebAssembly module | ||
| GOOS=wasip1 GOARCH=wasm go build -o hello.wasm | ||
| ``` | ||
|
|
||
| ### Run with WasmEdge | ||
|
|
||
| ```bash | ||
| wasmedge hello.wasm | ||
| ``` | ||
|
|
||
| Expected output: | ||
|
|
||
| ``` | ||
| Hello, world | ||
| ``` | ||
|
|
||
| Ensure the example prints "Hello, world" when run with WasmEdge. This section is intentionally minimal to demonstrate the native Go WASI path working end-to-end. | ||
|
|
||
|
|
||
| ## Building a WASI module with Go 1.21 | ||
|
|
||
| To compile a Go application to a WASI-compatible WebAssembly module, Go 1.21 or newer is required. | ||
|
|
||
| Use the following environment variables when building your application: | ||
|
|
||
| ```bash | ||
| GOOS=wasip1 GOARCH=wasm go build -o app.wasm | ||
aaradhychinche-alt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| In this command: | ||
|
|
||
| GOOS=wasip1 specifies the WASI Preview 1 target | ||
|
|
||
| GOARCH=wasm selects the WebAssembly architecture | ||
|
|
||
| app.wasm is the generated WebAssembly module | ||
|
|
||
| The resulting .wasm file can be executed by WASI-compliant runtimes such as WasmEdge. | ||
|
|
||
|
|
||
| ## Running the module with WasmEdge | ||
|
|
||
| After building the WebAssembly module (for example, `app.wasm`), it can be executed using the WasmEdge CLI. | ||
|
|
||
| ```bash | ||
| wasmedge app.wasm | ||
| ``` | ||
|
|
||
| WasmEdge executes the WASI _start entry point by default. Command-line arguments provided after the module path are forwarded to the module at runtime. The --dir option can be used to preopen host directories for file system access when required. | ||
|
|
||
|
|
||
| ## Networking and WASI limitations | ||
|
|
||
| The current WASI Preview 1 specification does not include native support for networking primitives such as TCP or UDP sockets. As a result, Go packages that depend on the standard `net` or `net/http` libraries cannot function out of the box in a WASI environment. | ||
|
|
||
| This limitation applies to both TinyGo and native Go when targeting WASI and is not specific to WasmEdge. Networking support requires additional abstractions or host-provided functionality, which are discussed in the following sections. | ||
|
|
||
|
|
||
| ## Networking with stealthrocket/net | ||
aaradhychinche-alt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| To work around the lack of native networking support in WASI Preview 1, | ||
| alternative approaches are required. One such experimental approach is the use | ||
| of the external `stealthrocket/net` project, which provides a networking | ||
| implementation designed for WASI environments. | ||
|
|
||
| Rather than relying on traditional socket APIs, `stealthrocket/net` forwards | ||
| network requests to host-provided functionality. This can enable limited HTTP | ||
| and networking capabilities for Go applications compiled to WASI, depending on | ||
| the runtime environment. | ||
|
|
||
| > **Note** | ||
| > `stealthrocket/net` is **not part of WasmEdge** and is mentioned here only as an | ||
| > external reference. Usage details, compatibility, and examples should be | ||
| > verified directly with the project maintainers. | ||
|
|
||
| For more information, see the official repository: | ||
| - https://github.com/stealthrocket/net | ||
|
|
||
|
|
||
|
|
||
| ## Importing host functions in native Go (Go 1.21+) | ||
|
|
||
| Native Go applications compiled to WASI can call functions that are implemented | ||
| by the WebAssembly runtime (such as WasmEdge) rather than inside the module | ||
| itself. | ||
|
|
||
| Starting with Go 1.21, host functions can be declared using the | ||
| `//go:wasmimport` directive. | ||
|
|
||
| ### Example | ||
|
|
||
| ```go | ||
| package main | ||
|
|
||
| //go:wasmimport wasi_snapshot_preview1 proc_exit | ||
| func procExit(code uint32) | ||
|
|
||
| func main() { | ||
| procExit(0) | ||
| } | ||
| ``` | ||
|
|
||
| In this example, proc_exit is a WASI host function provided by the runtime. | ||
| The implementation is supplied by the WASI environment rather than by Go code | ||
| inside the WebAssembly module. | ||
|
|
||
| For more details, see the official Go documentation: | ||
| - https://pkg.go.dev/cmd/compile#hdr-Directives | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.