Juno is a talking character built in Rive. Press play and a real voice line drives her mouth, word by word, with live captions. Play the live Rive file

The brief
Lip-sync in apps is usually a video or a Lottie that cannot react. I wanted one Rive file a product team can drive from data: send it a voice line and it talks, set a mood and it changes expression, and it keeps looking at the user between lines.
What I built
One mouth that morphs through 12 visemes (Rest, M B P, A, E, EE, O, OO, F V, TH, L, S Z, R). Every shape uses the same vertices, so the state machine blends between them instead of swapping images.
A 16 second voice line keyed from its speech timing: 108 mouth changes, each easing in over 5 frames and landing 2 frames before the sound so it reads as in sync. The audio plays from an AudioEvent on the same state.
Captions that build word by word, keyed on the same timeline.
Three moods (Happy, Curious, Sleepy) that move brows, eyelids, cheeks and head tilt.
Blinks, breathing, hair sway, and eyes plus face that follow the pointer through a joystick.
How it is wired

A view model exposes viseme (number), mood (number) and speak (trigger). The panel writes those values with listeners, so a developer drives the exact same inputs from code. The file fires lineStarted and lineEnded events back to the host app.
Result
A single .riv that talks, emotes and reacts, with no video and no per-line exports. Swap the voice line and its timing data and she says something new.
0 likes · 1 view · Nov 11, 2026
A Rive character that lip-syncs a real voice line: one mouth morphing through 12 visemes, moods, blinks and pointer tracking, all driven by data.