This library provides two different approaches for loading and working with WebAssembly modules in modern web applications using Svelte 5. It's designed to be used as a git submodule in other projects.
The ModernWasm library supports two distinct WASM loading approaches:
- WASI Approach (Recommended) - Modern, standards-based WASM loading with class-based architecture
- Legacy Go Runtime Approach(LegacyApproach folder) - Traditional Go wasm_exec.js runtime simulation
ModernWasm/
├── wasi-loader.svelte.ts # WASI WASM loader (class-based, @wasmer/wasi and @wasmer/sdk)
├── debugLogger.svelte.ts # Shared debug logging
├── LegacyApproach
| ├── wasm-loader.svelte.ts # Legacy Go runtime loader
| ├── wasm-exec.svelte.ts # Go wasm_exec.js wrapper
| ├── go-runtime.svelte.ts # Go runtime management
| ├── go-runtime.worker.ts # Web Worker for Go runtime
|
└── README.md # This file
- ✅ Standards-based: Uses WebAssembly System Interface (WASI)
- ✅ Class-based: Each
WasiLoaderinstance manages its own WASM module - ✅ Lightweight: No heavy Go runtime required
- ✅ Fast startup: Direct WebAssembly instantiation
- ✅ Browser native: Uses
@wasmer/sdkfor WASI support - ✅ Type safe: Strong TypeScript integration
- ✅ Memory efficient: Clean memory management
- ✅ Multiple modules: Can load different WASM modules simultaneously
import { WasiLoader } from './wasi-loader.svelte';
// Create a dedicated loader instance for your specific WASM module
const myWasiLoader = new WasiLoader();
// Load a WASI WASM module
const success = await myWasiLoader.loadWasm('/path/to/module.wasm');
if (success && myWasiLoader.isReady) {
// Call exported functions
const result = myWasiLoader.callFunction('YourExportedFunction', arg1, arg2);
// Access exports directly
const exports = myWasiLoader.exports;
// Read memory
const data = myWasiLoader.readMemory(offset, length);
}
// Each WasiLoader instance maintains its own state
const anotherLoader = new WasiLoader();
await anotherLoader.loadWasm('/another-module.wasm'); // Won't interfere with myWasiLoaderimport { loadWasiWasm, callWasiFunction, wasiLoaderState } from './wasi-loader.svelte';
// Uses the default global instance
const success = await loadWasiWasm('/path/to/module.wasm');
if (success && wasiLoaderState.isReady) {
// Call exported functions
const result = callWasiFunction('YourExportedFunction', arg1, arg2);
// Access exports directly
const exports = wasiLoaderState.exports;
}GOOS=wasip1 GOARCH=wasm go build -o module.wasm main.go//go:wasmexport YourFunction
func YourFunction(param1, param2 int32) int32 {
// Your implementation
return result
}- ✅ Go compatibility: Full Go runtime available
- ✅ Mature: Well-tested approach
- ✅ Rich API: Access to full Go standard library
⚠️ Heavier: Larger runtime overhead⚠️ Go-specific: Not standards-based⚠️ Experimental: Simulateswasm_exec.jsbut may not work correctly for all Go WASM modules
wasm-loader.svelte.ts- Main legacy loader with Svelte 5 runeswasm-exec.svelte.ts- Go wasm_exec.js wrappergo-runtime.svelte.ts- Go runtime lifecycle managementgo-runtime.worker.ts- Web Worker for Go runtimedebugLogger.svelte.ts- Shared logging utilities
import { loadWasm, wasmLoaderState } from './wasm-loader.svelte';
// Load a Go WASM module
const success = await loadWasm('/path/to/calculator.wasm');
if (success && wasmLoaderState.isReady) {
// Access functions via exports
const exports = wasmLoaderState.exports;
const result = exports.YourFunction(arg1, arg2);
// Or access data via globalThis (if exposed by Go code)
const data = (globalThis as any).yourData;
}GOOS=js GOARCH=wasm go build -o calculator.wasm main.goimport "syscall/js"
func main() {
// Register functions on global object
js.Global().Set("YourFunction", js.FuncOf(yourFunctionWrapper))
// Keep the program running
select {}
}{
"@wasmer/sdk": "^0.9.0"
}Experimental Svelte 5 version of wasm_exec.js. Simulates the Go runtime in the browser and does not require the actual wasm_exec.js from your Go installation.
wasm_exec.js working, but results may vary and some features may be incomplete or unreliable.
This library requires proper UTF-8 encoding. The project includes:
.editorconfig- Ensures UTF-8 encoding for all text files.gitattributes- Forces UTF-8 encoding in Git- VS Code settings - Configured for UTF-8
- PowerShell setup script (
setup-utf8.ps1) - Configures terminal for UTF-8
The WASI loader requires Node.js Buffer API for binary data handling. This project includes automatic Buffer polyfill injection:
- Vite Configuration: Automatically includes Buffer polyfill in builds
- Client Hooks: Injects Buffer globally before app initialization
- Dependencies:
bufferpackage provides browser-compatible Buffer implementation
If you see ReferenceError: Buffer is not defined, ensure:
- The
bufferpackage is installed:pnpm add buffer - Vite config includes Buffer polyfill settings
- Client hooks (
src/hooks.client.ts) are properly configured
SvelteKit may encounter JSON parse errors from corrupted session storage. The app includes automatic cleanup:
- Automatic Recovery: Detects and removes corrupted session storage entries
- Manual Cleanup: Use
scripts/clear-session-storage.jsin browser console - Complete Reset: Run
sessionStorage.clear()in console if needed
See BROWSER_ERROR_FIXES.md for detailed troubleshooting.
Both loaders expose reactive state using Svelte 5 runes:
import { WasiLoader } from './wasi-loader.svelte';
const loader = new WasiLoader();
$effect(() => {
if (loader.isReady) {
console.log('WASM module loaded successfully');
console.log('Available exports:', Object.keys(loader.exports));
}
if (loader.hasError) {
console.error('WASM loading failed:', loader.error);
}
});import { wasmLoaderState } from './wasm-loader.svelte';
$effect(() => {
if (wasmLoaderState.isReady) {
console.log('WASM module loaded successfully');
console.log('Available exports:', Object.keys(wasmLoaderState.exports));
}
if (wasmLoaderState.hasError) {
console.error('WASM loading failed:', wasmLoaderState.error);
}
});- Building new projects
- Want modern, standards-based approach
- Need lightweight, fast-loading modules
- Prioritize performance and browser compatibility
- Using simple exported functions
- Need to load multiple WASM modules simultaneously
- Migrating existing Go WASM projects
- Need full Go runtime features
- Have complex Go code dependencies
- Already invested in Go wasm_exec.js approach
To use this library in another project:
-
Add as submodule:
git submodule add <repo-url> src/lib/ModernWasm
-
Install dependencies:
# For WASI approach npm install @wasmer/sdk -
Set up UTF-8 encoding:
# Run the setup script (Windows/PowerShell) .\setup-utf8.ps1
-
Import and use:
// WASI approach (class-based) import { WasiLoader } from '$lib/ModernWasm/wasi-loader.svelte'; const loader = new WasiLoader(); // WASI approach (global instance) import { loadWasiWasm } from '$lib/ModernWasm/wasi-loader.svelte'; // Legacy approach import { loadWasm } from '$lib/ModernWasm/wasm-loader.svelte';
When contributing to this library:
- Maintain compatibility with both approaches
- Update both README sections for new features
- Ensure TypeScript types are complete
- Test with real WASM modules
- Keep debug logging comprehensive
- Ensure proper UTF-8 encoding
MIT License - See LICENSE file for details.