WebAssembly & TinyGo Best Practices
Testing WASM builds in CI and avoiding syscall/js in server modules.
Search across all documentation pages
Testing WASM builds in CI and avoiding syscall/js in server modules.
These rules keep WASM artifacts portable, sandbox-friendly, and sized appropriately from first spike through production hosts.
GOOS=wasip1 GOARCH=wasm compile and wasmtime run smoke steps to CI for guest packages.wasip1/wasm. Reserve js/wasm for browser DOM requirements only.syscall/js in WASI packages. Enforce with js && wasm build tags on browser files.-ldflags="-s -w". Keep unstripped artifacts in CI storage for crash triage.go list -deps for guest mains. Reject accidental net/http/pprof or test-only imports in plugin entrypoints.GOOS=wasip1 GOARCH=wasm go build ./... catches import regressions early.tinygo build -target=wasm may fail while gc builds pass.--dir / wazero FSConfig).ls -lh on the same feature slice, not hello-world only..wasm.wasm_exec.js with your Go toolchain. Mismatch causes obscure import failures in browsers.js.Func.Release() when removing listeners. Prevent leaks on long-lived SPA pages.main with select {} in browser guests. Exiting main tears down the runtime before callbacks fire..wasm as application/wasm. Fix static server MIME maps for instantiateStreaming.go fix modernizers on shared packages. Go 1.26 go fix keeps code idiomatic before cross-compiling to WASM.Compiling server plugins to js/wasm or leaking syscall/js into wasip1 builds.
Default to wasip1 and enforce build tags in review.
GOOS=wasip1 GOARCH=wasm go build plus wasmtime run on at least one representative guest binary per module.
Whenever production deploy artifacts are produced with TinyGo, including MCU firmware and size-capped edge WASM.
Add spin build and route tests; HTTP triggers may replace raw net/http listeners in guests.
Yes in go.mod alongside Go 1.26.x.
Runtime APIs evolve; upgrades should run embed integration tests.
signext and satconv are ignored per release notes.
Read current docs each upgrade instead of copying old flags.
Use wasmtime run --dir $(pwd)::/work (or tighter paths) and keep the same mounts in wazero ModuleConfig.
Chosen toolchain, size/memory measurements, rejected alternatives, host runtime, and capability matrix for FS/env/network.
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026