Skip to main content
This gets you from an installed package to a talking avatar. If you have not installed yet, do Installation first.

1. Mount the provider

<MascotProvider> initializes a single LipsyncClient for your app and exposes it through context.
Anywhere inside it, useMascot() gives you the client and status, and useProcessAudio() fetches a URL, decodes, resamples to 16 kHz, and runs inference once:
result.timeline is a VisemeTimeline — hand it to playback below, or JSON.stringify it to persist and replay later with zero reprocessing.

2. Drive a Rive avatar

Wire the timeline into a Rive avatar’s mouth state machine with the /rive subpath:
useProcessAudio runs inference once. Persist result.timeline (it is plain JSON) and on later loads skip decode + inference entirely: playback.setTimeline(parseTimeline(JSON.parse(stored))). See Offline lip sync.

Rive avatar requirements

If you author your own .riv file: The SDK writes only those inputs. Any other input, data binding, or event on the file is yours to drive on the raw rive instance (useMascotRive().rive) — see Rive co-existence. Or skip authoring entirely and use a ready-made mascot.

3. Live microphone input

Drive the avatar from the user’s microphone in real time with useLipsyncStream:
The audio worklet is embedded in the SDK and served from a Blob URL by default — there is no file to copy. Pass workletUrl only if your CSP forbids worker-src blob:. The same hook handles realtime AI providers via source: { kind: "mediaStream", stream } — see Realtime providers.

4. Vanilla JavaScript

Not using React? Use @mascotbot/core directly:
For the Rive engine without React, import from @mascotbot/core/rive — see Core SDK.

Error handling

useMascot() exposes status and error. Branch on error.code, not the subclass:
Full matrix: Error codes.

Next

Offline lip sync

Generate → persist → replay.

React hooks

The full hook reference.

Realtime providers

OpenAI, Gemini, ElevenLabs.