TypeScript needs a compile step. The simplest path is esbuild — one devDep, one CLI command. Install @wvdsh/sdk-js and import the typed Wavedash singleton.
Install dependencies
npm install @wvdsh/sdk-js
The default export is the live SDK instance — fully typed, so methods, events, and payloads all autocomplete.
Setup
my-game/
├── wavedash.toml
├── package.json
├── tsconfig.json
├── src/main.ts # source
└── web/
├── index.html # loads ./main.js
└── main.js # esbuild output (gitignored)
package.json
{
"name": "my-game",
"private": true,
"scripts": {
"build": "esbuild src/main.ts --bundle --format=esm --target=es2022 --outfile=web/main.js"
},
"dependencies": {
"@wvdsh/sdk-js": "^1.3.0"
},
"devDependencies": {
"esbuild": "^0.24.0",
"typescript": "^5.8.3"
}
}
src/main.ts
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";
// ... game setup ...
Wavedash.updateLoadProgressZeroToOne(1);
Wavedash.init({ debug: true });
// start main loop
Call updateLoadProgressZeroToOne(...) with intermediate values during async asset loading. init() automatically signals load completion, so call it last.
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.js"></script>
</body>
</html>
Build and run
npm install
npm run build
wavedash dev
wavedash.toml
game_id = "YOUR_GAME_ID_HERE"
upload_dir = "./web"
SDK features
Once initialized, Wavedash exposes leaderboards, achievements, stats, and user data — all fully typed:
const user = Wavedash.getUser();
const lb = await Wavedash.getLeaderboard("high-scores");
await Wavedash.uploadLeaderboardScore(lb.data.id, score, true);
Wavedash.setAchievement("first_clear", true);