A Tampermonkey Script Gives Any LLM a 3D Avatar on Every Webpage
Most LLM interfaces are still text boxes. This script shows how cheaply a multimodal, embodied agent layer can be bolted onto any existing model and deployed across the entire web, turning a reasoning engine into a persistent, interruptible presence that works on commodity hardware.
A frontend developer has released a Tampermonkey script that places a fully interactive 3D avatar onto every webpage a user visits. The avatar is rendered by the Mofa Nebula embodied driving SDK, which handles sub-500ms voice synthesis, facial expressions, and body movements on low-cost hardware without a game engine. The script connects to any LLM—DeepSeek is built in by default—and streams the model's text output directly to the avatar's speech engine, so the character begins speaking before the full response is generated.
Voice input is also supported through a third-party ASR service, creating a full bidirectional conversation loop. Avatar appearance, scene, and voice can be hot-swapped from the Mofa Nebula console with zero code changes. The entire setup requires only a browser extension, an SDK key, and optionally a personal LLM API key.
The project treats the LLM as the brain, the SDK as the body and voice, and the userscript as the delivery mechanism. The result is an AI companion that follows a user across domains rather than being trapped inside a single chat window.
The architecture cleanly separates concerns: the LLM is just a text generator, the SDK is a pure expressiveness layer, and the userscript is a zero-friction distribution channel. None of the three pieces needs to know about the others.
Hot-swapping the avatar from a cloud console without touching code is a small detail that removes the usual friction of redeploying frontend assets, making non-technical iteration on the character's look and feel trivial.
Streaming TTS that starts mid-generation is the feature that makes the interaction feel conversational rather than like a buffered playback, and it requires almost no extra work beyond segmenting the LLM's stream.