The recommended setup is a small bundler (esbuild) plus the @wvdsh/sdk-js package — that gives you a real import Wavedash from "@wvdsh/sdk-js" and full editor autocomplete on every method, event, and payload. If you want to skip the build step entirely, see the vanilla JS path at the bottom of the page.
Install dependencies
npm install @wvdsh/sdk-js
The default export is the live, fully-typed Wavedash SDK singleton.
Setup
my-game/
├── wavedash.toml
├── package.json
├── src/main.js # source
└── web/
├── index.html # loads ./main.bundle.js
└── main.bundle.js # esbuild output (gitignored)
package.json
{
"name": "my-game",
"private": true,
"scripts": {
"build": "esbuild src/main.js --bundle --format=esm --target=es2022 --outfile=web/main.bundle.js"
},
"dependencies": {
"@wvdsh/sdk-js": "^1.3.0"
},
"devDependencies": {
"esbuild": "^0.24.0"
}
}
web/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Game</title>
<style>
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #111; }
#gameCanvas { width: 100%; height: 100%; display: block; }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<script type="module" src="./main.bundle.js"></script>
</body>
</html>
src/main.js
Calling Wavedash.init() is required. Your game stays hidden behind the Wavedash loading screen until you do. Call it once your game is ready to play.
import Wavedash from "@wvdsh/sdk-js";
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
// ... game setup ...
Wavedash.updateLoadProgressZeroToOne(1);
Wavedash.init({ debug: true });
let last = performance.now();
(function loop(now) {
const dt = Math.min(0.05, (now - last) / 1000);
last = now;
update(dt);
draw();
requestAnimationFrame(loop);
})(last);
Call updateLoadProgressZeroToOne(...) with intermediate values during async asset loading. init() automatically signals load completion, so call it last.
Build and run
npm install
npm run build
wavedash dev
wavedash.toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./web"
Vanilla JS, no build step
If your game is plain JavaScript and you'd rather skip the bundler, just use window.Wavedash directly — the host injects it before your code runs. Drop the <script type="module" src="./main.bundle.js"> for a plain <script src="./main.js">, and write main.js against the global:
/// <reference types="@wvdsh/sdk-js" />
const Wavedash = window.Wavedash;
Wavedash.updateLoadProgressZeroToOne(1);
Wavedash.init({ debug: true });
The triple-slash reference is optional — when @wvdsh/sdk-js is installed, it tells VS Code (and other LSP-aware editors) to load the SDK's types so window.Wavedash becomes fully typed in the rest of the file. The line is a comment, so nothing executes and you still have zero build step. Without the reference (or without the package installed) the SDK still works — you just lose autocomplete.
SDK features
Once initialized, Wavedash exposes leaderboards, achievements, stats, and user data:
const user = Wavedash.getUser();
const lb = await Wavedash.getLeaderboard("high-scores");
await Wavedash.uploadLeaderboardScore(lb.data.id, score, true);
Wavedash.setAchievement("first_clear", true);