Examples
The @hapbeat/sdk repo’s examples/ contains runnable samples ordered from smallest to largest. They are a foundation to copy and bring into your own project.
How to get the examples
Section titled “How to get the examples”Reading order
Section titled “Reading order”We recommend reading them progressively: start with the minimal fire, then the browser path, and finally the real-app-scale arcade.
examples/node-minimal.mjs— one round trip ofconnect()→play(id)→close()over UDP from Node. Grasps the SDK’s minimal loop.examples/browser-minimal.html— the exact same calls, sent from the browser via the helper’s WebSocket. Confirms that the API is identical in Node and the browser.examples/react-native/— a minimal Android demo where a button tap sends a command (play) plus a 1 s synthesized streaming buffer. A phone is not sandboxed like a browser, so it sends a direct UDP broadcast viareact-native-udp(no helper needed).examples/games/(Hapbeat Arcade) — a real-app-scale setup that also includes EventMap + kit manifest + a “file-first / synth-fallback” router.
For the transport difference (Node = direct UDP / React Native = direct UDP via react-native-udp / Browser = helper WS), see Transports — Node UDP / React Native UDP / Browser helper.
Sample table
Section titled “Sample table”| Sample | Target | What it shows | Kit needed? |
|---|---|---|---|
node-minimal.mjs | Node | connect() → play(id) → close() over UDP | a Hapbeat on the LAN + a deployed kit, if you want haptics |
browser-minimal.html | Browser | the same calls via the helper WebSocket | hapbeat-helper running + HTTP serving |
react-native/ | React Native (Android) | a button tap sends a command (play) + a 1 s synthesized stream over direct UDP (helper-free); verified on Android (RN 0.86) | a Hapbeat on the LAN + a deployed kit. Needs react-native-udp + the fast-text-encoding polyfill (see the example’s README / Transports — Node UDP / React Native UDP / Browser helper) |
games/ (Hapbeat Arcade) | Browser | a worked instance of EventMap + kit manifest + a file/synth router (FPS + mini-games) | HTTP serving. Haptics need helper + demo-kit |
The two minimal samples are designed to “launch even with no device on the LAN” (they send command-mode events, which are simply ignored if no device is present). The arcade can be tried with sound and visuals alone, even without a device or helper.
Running (the two minimal samples)
Section titled “Running (the two minimal samples)”# Node — run as isnode examples/node-minimal.mjs
# Browser — serve over HTTP from the repo root (see below)npm run dev# → open http://localhost:8170/examples/browser-minimal.htmlThe browser path requires the helper (pip install hapbeat-helper → run hapbeat-helper to listen on ws://localhost:7703). For details, see Transports — Node UDP / React Native UDP / Browser helper.
Hapbeat Arcade (examples/games/) {#arcade}
Section titled “Hapbeat Arcade (examples/games/) {#arcade}”examples/games/ is a haptic demo arcade that runs on the browser transport + helper. It collects mini-games playable in 1–2 minutes each at an exhibition, all aiming for an experience that only works / changes because the haptics are there (an invisible-wall maze / a haptic rhythm game / a treasure hunt / a reaction-time game). Each game has a modality switch to toggle audio, visuals, and haptics individually, allowing an A/B comparison with “haptics only.”
Structure
Section titled “Structure”Browser (this demo) │ @hapbeat/sdk → ws://localhost:7703 ▼hapbeat-helper (pip install hapbeat-helper) │ UDP 7700 broadcast ▼Hapbeat device (demo-kit deployed)examples/games/demo-kit/ (hapbeat-arcade-manifest.json + install-clips/*.wav) is the Kit to deploy to the device. If you Deploy it to the target device from Hapbeat Studio, the haptics corresponding to the event ids the games send (e.g. hapbeat-arcade.maze_bump) will play. The games still run without deploying it — only the haptics are silent (the event isn’t on the device, so it’s ignored).
How to run
Section titled “How to run”# 1. Start the helper (install on first use only)pip install hapbeat-helperhapbeat-helper # listens on ws://localhost:7703
# 2. Serve the demo over HTTP (from the repo root)npm run dev # builds dist/ + tsc --watch + static serving + auto-reload# → open http://localhost:8170/examples/games/# (change the port with PORT=8080 npm run dev)Editing src/*.ts rebuilds dist/ and auto-reloads the browser. npm run serve only serves the built dist/ statically (no watch).
Worked instances of the EventMap / manifest / router patterns
Section titled “Worked instances of the EventMap / manifest / router patterns”The arcade is a reference implementation that translates the ideas explained in this documentation into real code.
- kit manifest — reads it to resolve per-event default intensity (EventMap reference).
demo-kit/hapbeat-arcade-manifest.jsonis a schema 2.0.0 kit manifest. - command vs clip router — the mode is split by the manifest bucket (
events= command /stream_events= clip), and the game code just callsplay(id), unchanged (Command vs Clip). - file-first / synth-fallback —
shared/event-content.jsconsolidates each event’s haptic (synthesized PCM) + sound in one file, falling back to synthesis when the kit/WAV is absent. This is the starting point (source of truth) for tuning.
Each event’s clip / intensity is a placeholder borrowed from Studio’s showcase-kit, with final tuning expected to be done by the user (mapping table: TUNING.md).
Pitfalls
Section titled “Pitfalls”- Won’t run from
file://— ES Modules + import map + WAV fetch cannot be read from the file system. Always serve over HTTP (npm run dev/npx serve .). If you get a blank page or a module error, suspect this first. - The browser path requires a running helper — without the helper,
connect()cannot reachws://localhost:7703and rejects. The arcade can be tried with sound and visuals alone even without the helper, but no haptics come out. - Multi-homed (multiple NIC) PC — if Wi-Fi and Ethernet are connected at the same time, the UDP broadcast may go out the unintended NIC and never reach the device. Make sure there is a route on the NIC on Hapbeat’s LAN side, or disconnect one of them.
- Sound and visuals come out but no haptics — the most common cause is that the event id is not in the deployed kit. Check whether
discover()sees the device and whether the event name matches the manifest (Getting Started).
Related
Section titled “Related”- EventMap reference — resolving default intensity from a kit manifest
- Command vs Clip — choosing between command and clip
- Streaming — clips & ad-hoc PCM — clip streaming
- Live Streaming (openStream) — continuous streams (
openStream)