Swift compiles to WebAssembly via the official Swift WebAssembly SDK, and JavaScriptKit gives you typed access to browser globals. Any Swift program that can drive a <canvas> through JavaScriptKit runs on Wavedash.
Toolchain
Apple's bundled toolchain doesn't ship a wasm-capable clang, so install a standalone Swift 6.3+ toolchain from swift.org. swiftly is the easiest path:
swiftly install 6.3.0
Then install the Swift WebAssembly SDK once:
swift sdk install https://download.swift.org/swift-6.3-release/wasm-sdk/swift-6.3-RELEASE/swift-6.3-RELEASE_wasm.artifactbundle.tar.gz \
--checksum 9fa4016ee632c7e9e906608ec3b55cf13dfc4dff44e47574c5af58064dc33fd9
Build for web
In your Package.swift, add JavaScriptKit and its PackageToJS plugin. Build with:
swift package --swift-sdk swift-6.3-RELEASE_wasm js -c release
cp -R .build/plugins/PackageToJS/outputs/Package/. dist/
cp Public/index.html dist/
The PackageToJS plugin emits the WASM binary plus a loader in .build/plugins/PackageToJS/outputs/Package/. Point upload_dir at the dist/ folder you assemble.
SDK integration
Wavedash injects window.Wavedash before your wasm loads, so Swift can reach it through JavaScriptKit directly:
import JavaScriptKit
let window = JSObject.global
// Set up canvas, input, game loop with requestAnimationFrame...
if let sdk = window.Wavedash.object {
_ = sdk.updateLoadProgressZeroToOne!(1.0)
let opts = JSObject.global.Object.function!.new()
opts.debug = .boolean(true)
_ = sdk.`init`!(opts)
}
Calling async SDK methods (leaderboards, UGC, etc.) works through JavaScriptKit's JSPromise — see the SDK setup and Functions reference pages for the full API.
wavedash.toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./dist"
entrypoint = "index.html"
The example repo commits a prebuilt dist/ so you can run wavedash dev without a Swift wasm toolchain. Regenerate it by re-running the swift package ... js -c release command whenever you change Swift sources.