Web SDK

Local transcription for apps that already live in the browser.

@voxd/client gives web apps a direct path to Vox Companion on the user's Mac: probe availability, transcribe blobs, align remote audio, and fall back gracefully when the local bridge is unavailable.

Read integration docs
SDK flow
import { createVoxdClient } from "@voxd/client"
const client = createVoxdClient()
if (await client.probe()) {
await client.transcribe({ audio: blob })
}
probe()transcribe()align()launch()

A clean browser story, without pretending the browser owns the runtime.

Browser-native API

Send a Blob, File, or ArrayBuffer straight from the browser. No backend proxy needed when the companion is present.

Probe first

Call probe() on page load, fail fast, and degrade cleanly when the companion is not installed or not running.

Transcribe or align

Use transcribe() for local audio and align() when the companion should fetch audio from a URL and return word timings.

Private by default

Audio stays on the user's Mac when the companion handles the work. That makes the web SDK a strong fit for internal tools and pro workflows.

How it works

Install the package, detect the companion, then choose the right local path.

The package is intentionally narrow. It does not try to own media capture or browser permissions. It just gives your app a clean bridge to the local Vox runtime.

Add the browser SDK to your web app.

Create the local bridge client.

Check whether the companion is available on this Mac.

Send captured audio to the local runtime and get transcript text plus timing data.

Design constraints

The browser SDK should stay boring where boring is correct.

It should not hide runtime availability. Call probe(), show a clear install or launch path, and degrade when the companion is unavailable.

It should not pretend every app wants the same audio path. Use transcribe() for local blobs and align() when the runtime should fetch audio itself.

And it should preserve the local-first story: audio stays on the Mac, while the web app gets a small, typed bridge instead of another heavyweight backend dependency.