English | δΈζ
Porting firefly (React + three.js 3D digital human) to Electron, the main process loads C++ native modules (audio energy / VAD / microphone capture / ASR / TTS wrapper) via node-addon-api, integrating Whisper.cpp local speech recognition, Piper local speech synthesis, music player, and other features, with support for setting breakpoints and debugging C++ code directly in VSCode.
| Layer | Technology |
|---|---|
| Application Shell | Electron 37 + electron-vite |
| Renderer Process | React 18 + three.js + @react-three/fiber + @react-three/drei (3D digital human) |
| Native Module | C++17 + node-addon-api (audio energy / VAD / ASR / TTS wrapper) |
| Speech Recognition | Whisper.cpp (local offline ASR) |
| Speech Synthesis | Piper (local offline TTS) |
| Audio Processing | RNNoise (noise suppression) + CoreAudio (audio playback) |
| Debugging | VSCode: Node debug main process + lldb attach debug C++ |
work/electron/firefly-studio/
βββ electron.vite.config.mjs # electron-vite three-process build config
βββ Makefile # Build and development commands
βββ package.json # Project dependencies and scripts
βββ .env.example # Environment variable config template
βββ .gitignore # Git ignore rules
β
βββ scripts/ # Build and deployment scripts
β βββ prepare-electron.sh # One-click Electron setup + native rebuild
β βββ install-electron.sh # Electron install script (supports proxy)
β βββ build-native.sh # C++ native module build script
β βββ dev.sh # dev startup wrapper (Ctrl+C clean exit)
β
βββ src/ # Application source code
β βββ main/ # Main process
β β βββ index.js # Main process entry: load .node + IPC bridge + window management
β β βββ asr.js # ASR speech recognition service (Whisper.cpp)
β β βββ tts.js # TTS speech synthesis service (Piper)
β β βββ retry-utils.js # Retry and daemon process utilities
β βββ preload/ # Preload scripts
β β βββ index.js # contextBridge secure API exposure
β βββ renderer/ # Renderer process (React)
β βββ index.html # HTML entry
β βββ src/
β βββ App.jsx # Main app component (digital human + chat + music player)
β βββ main.jsx # React entry
β βββ components/ # UI components
β β βββ Stage.jsx # 3D digital human stage
β β βββ AvatarVRM.jsx # VRM model rendering
β β βββ MusicPlayer.jsx # Music player
β β βββ ...
β βββ hooks/ # Custom Hooks
β β βββ useResolveChat.ts # LLM chat Hook (SSE streaming)
β β βββ useMic.js # Microphone capture Hook
β β βββ ...
β βββ utils/ # Utility functions
β βββ audioEffects.js # Audio effects processing (EQ, reverb, etc.)
β βββ ...
β
βββ native/ # C++ native module
β βββ binding.gyp # node-gyp build config
β βββ package.json # Native module package.json
β βββ src/ # C++ source code
β β βββ addon.cc # N-API entry (handle table + JS binding)
β β βββ audio_engine.* # Audio energy / VAD detection (pure C++)
β β βββ mic_capture.* # Microphone capture (CoreAudio)
β β βββ asr_whisper.* # Whisper ASR wrapper
β β βββ ...
β βββ asr/ # ASR related configs and scripts
β βββ models/ # Whisper model files (not committed to Git)
β βββ piper/ # Piper TTS service
β β βββ piper_server.py # Piper TTS persistent service
β β βββ models/ # Piper voice models (not committed to Git)
β βββ piper-cpp/ # Piper C++ wrapper (experimental)
β βββ rnnoise/ # RNNoise noise suppression library
β βββ whisper.cpp/ # Whisper.cpp third-party library (cloned during build)
β βββ build/ # Build artifacts (not committed to Git)
β
βββ server/ # Built-in lightweight backend (optional)
β βββ standalone.js # Standalone LLM chat service (no tool calling)
β
βββ .vscode/ # VSCode debug config
β
βββ docs/ # Project documentation
β
βββ CREDITS.md # Third-party materials credits
βββ LICENSE # MIT License
βββ PRIVACY.md # Privacy Policy
βββ SECURITY.md # Security Policy
βββ TODO.md # TODO items
βββ README.md # English project docs (this file)
βββ README.zh.md # Chinese project docs
make install # Install dependencies
make prepare # Download Electron + rebuild C++ native module for its ABI
make dev # Start ElectronWhy
make prepareis needed: The official Electron binary source is unstable in mainland China networks, and the Electron runtime architecture may differ from the machine architecture (e.g., running x64 Electron via Rosetta on Apple Silicon). This script downloads Electron using the npmmirror mirror, extracts it tonode_modules/electron/dist, automatically detects the runtime architecture, and useselectron-rebuildto recompile for the Electron ABInative/build/Release/firefly_native.node(otherwise you'll getERR_DLOPEN_FAILED).
After opening the app, you can experience the following core features:
- 3D Digital Human Interaction β Click the digital human to trigger random conversations and expression animations
- Voice Conversation β Click the microphone button for voice input (Whisper.cpp local recognition), the digital human replies with Piper local voice
- Text Chat β Type text in the input box, supports streaming output and Markdown rendering
- Music Playback β Built-in music player, supports playlists, equalizer, volume control, music ducking (automatically lower music volume when digital human speaks)
- Character Switching β Supports multiple digital human characters (Firefly Maid, etc.), switchable in settings
- C++ Native Module β Audio energy calculation, VAD voice activity detection, microphone capture, etc. are all implemented in C++, debuggable with breakpoints in VSCode
The chat functionality (LLM conversation, tool calling) of Firefly Studio requires backend service support. There are two ways to use it:
Firefly Studio connects to resolve-studio's backend service (http://127.0.0.1:8787) by default, leveraging its complete agent loop, tool calling, PSE three-role, and other capabilities.
Startup Steps:
# 1. First start resolve-studio backend (in the resolve-studio project directory)
cd work/harness/resolve-studio
make dev # Start backend (8787) + frontend (5173), using real LLM model
# 2. Then start Firefly Studio (in this project directory)
cd work/electron/firefly-studio
make dev # Start Electron app, automatically connects to 127.0.0.1:8787resolve-studio Configuration:
- resolve-studio requires configuring the
.envfile with your LLM API key (supports OpenAI-compatible interfaces) - Default uses
cordis.openai.web.ymlconfig (real model) - For detailed configuration, see the README of the resolve-studio project
Advantages:
- Complete agent loop and tool calling capabilities
- Supports PSE three roles (Planner/Specialist/Evaluator)
- Rich tool ecosystem (article writing, investment analysis, resume optimization, interview question generation, etc.)
- Conversation history management, streaming output
Firefly Studio also comes with a lightweight built-in backend (server/ directory), supporting basic LLM conversation functionality, but does not support tool calling and PSE.
Configuration Steps:
- Copy
.env.exampleto.envand fill in the LLM configuration:
cp .env.example .env
# Edit .env, fill in:
# LLM_API_KEY=your-api-key-here
# LLM_BASE_URL=https://api.openai.com/v1
# LLM_MODEL=gpt-4o-mini- Modify the endpoint configuration in
src/renderer/src/App.jsx:
// Change the default resolve-studio address to the built-in backend address
const chat = useResolveChat({
endpoint: 'http://127.0.0.1:8788', // Built-in backend default port
model: 'gpt-4o-mini',
systemPrompt: currentCharacter.systemPrompt,
})- Start the app (
make devwill automatically start the built-in backend)
Built-in Backend Limitations:
- Only supports basic LLM conversation (streaming output)
- Does not support tool calling (article-write, juejin-draft, etc. tools are unavailable)
- Does not support PSE three roles
- Does not support conversation history persistence (managed by frontend localStorage)
| Service | Default Port | Description |
|---|---|---|
| resolve-studio backend | 8787 | Complete agent loop + tool calling (recommended) |
| Firefly built-in backend | 8788 | Lightweight LLM chat (no tool calling) |
| Firefly frontend (Vite) | 5180 | Electron renderer process dev server |
Note: If the port is occupied, you can modify the built-in backend port via
SERVER_PORTin.env. The resolve-studio port is modified viaBACKEND_PORTin itsMakefile.
Due to large file sizes and some licensing restrictions, model files are not included in git version control (already excluded in .gitignore). After first cloning, you need to manually download the following models:
Directory: src/renderer/public/
| Filename | Size | Type | Description |
|---|---|---|---|
fireflyMaid.vrm |
~14MB | VRM | Firefly Maid character (default character, third-party VRoid creation, OnlyAuthor + redistribution=disallow) |
avatar.vrm |
~11MB | VRM | VRoid anime style (with built-in facial blendshape, blink + lip sync) |
avatar.glb |
~10MB | GLB | Ready Player Me style realistic avatar |
avatar-avaturn.glb |
~2.6MB | GLB | Avaturn style static mesh (no facial blendshape) |
How to get:
- Download free VRM models from VRoid Hub, or use your own created models
- Or put your own VRM/GLB models into this directory and modify the loading path in
Stage.jsx - When models are missing, the app will automatically fall back to the built-in procedural character, no white screen
Note: All 3D model files (
*.glb,*.vrm) are excluded in.gitignoreand will not be committed to GitHub. After first cloning, you need to prepare model files yourself.
Directory: native/models/
| Filename | Size | Description |
|---|---|---|
ggml-base.bin |
~140MB | Whisper base model (Chinese-English recognition, balanced speed and accuracy) |
How to get:
# Download from Hugging Face
mkdir -p native/models
curl -L -o native/models/ggml-base.bin \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin- You can also download other sizes:
tiny(~75MB, faster),small(~460MB, more accurate),medium(~1.5GB) - After downloading, configure the model size via
ASR_MODELin.env(default base)
Directory: native/piper/models/
| Filename | Size | Description |
|---|---|---|
zh_CN-xiao_ya-medium.onnx + .json |
~60MB | Chinese Xiao Ya female voice (default, better punctuation pauses) |
en_US-amy-medium.onnx + .json |
~60MB | English Amy female voice (default, used for Chinese-English segmented speech) |
How to get:
# Download models from Hugging Face
mkdir -p native/piper/models
# Chinese Xiao Ya female voice (default)
curl -L -o native/piper/models/zh_CN-xiao_ya-medium.onnx \
https://huggingface.co/rhasspy/piper-voices/resolve/main/zh/zh_CN/xiao_ya/medium/zh_CN-xiao_ya-medium.onnx
curl -L -o native/piper/models/zh_CN-xiao_ya-medium.onnx.json \
https://huggingface.co/rhasspy/piper-voices/resolve/main/zh/zh_CN/xiao_ya/medium/zh_CN-xiao_ya-medium.onnx.json
# English Amy female voice (default)
curl -L -o native/piper/models/en_US-amy-medium.onnx \
https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/amy/medium/en_US-amy-medium.onnx
curl -L -o native/piper/models/en_US-amy-medium.onnx.json \
https://huggingface.co/rhasspy/piper-voices/resolve/main/en/en_US/amy/medium/en_US-amy-medium.onnx.json- For more models, see Piper Voices
- After downloading, configure the model to use via
PIPER_ZH_MODEL/PIPER_EN_MODELin.env
- 3D model missing: Automatically falls back to built-in procedural character, app runs normally
- ASR model missing: Speech recognition functionality unavailable, text chat unaffected
- TTS model missing: Piper local voice unavailable, voice playback disabled
Note: The above models are all open-source free models, please refer to their respective sources for license agreements. If using third-party created VRM models, please pay attention to complying with the original author's usage license (such as OnlyAuthor, redistribution=disallow, etc.).
π Complete Credits: For the source, author, and license information of all third-party materials (3D models, ASR/TTS models, open-source libraries) used in this project, please see CREDITS.md. If the model license requires "complete credits must be attached", please ensure this file is included when distributing.
- Install the extension CodeLLDB (
vadimcn.vscode-lldb) - First
make devto start the app - In VSCode "Run and Debug", select Debug C++ Native (lldb attach)
- Select the Electron process to attach, then set breakpoints in
native/src/*.cc
Note: lldb attaches to the entire Electron process, breakpoints will hit calls to this C++ module in any thread of the renderer/main process. If you only want to debug a specific call path, first let the app stop at the UI button that triggers that call.
When the main process starts, it prints [native] C++ module loaded @ <path>. If the module cannot be found, an error will be reported.
At this point, first execute make prepare (it will complete both electron deployment and native rebuild).
- β 3D Digital Human Rendering: Supports VRM/GLB models, facial expressions, lip sync, blink animation
- β Speech Recognition (ASR): Whisper.cpp local offline recognition, supports Chinese and English, streaming recognition
- β Speech Synthesis (TTS): Piper local offline synthesis, supports Chinese and English, automatic language switching
- β Voice Conversation: Microphone capture β ASR recognition β LLM conversation β TTS synthesis β digital human broadcast
- β Text Chat: Supports streaming output, Markdown rendering, code highlighting
- β Music Player: Playlist, equalizer (EQ), reverb, volume control, playback mode
- β Music Ducking: Automatically lower music volume when digital human speaks, restore after speaking
- β Character Switching: Supports multiple digital human characters, customizable character names and personalities
- β C++ Native Module: Audio energy, VAD, microphone capture, ASR/TTS wrapper
- β Theme Switching: Supports light/dark/follow system theme
- β Panel Layout: Collapsible left and right panels, draggable panel width adjustment
- β resolve-studio Integration: Can connect to resolve-studio backend, use complete agent loop and tool calling capabilities
- π§ Digital Human Singing: Voice synthesis (RVC / So-VITS-SVC and other solutions, RVC related code has been removed)
- π§ Gesture/Action Library: Richer digital human actions and gestures
- π§ Multimodal Input: Support image input and understanding
- π§ Conversation History Persistence: Chat record saving and loading
- π§ Plugin System: Support third-party plugin extension functionality
- The development environment of this repository is Apple Silicon;
scripts/prepare-electron.shwill automatically detect the Electron runtime architecture (arm64 / x64) and compile the corresponding version. - C++ modules must be compiled with the Electron corresponding ABI (
make prepare'selectron-rebuildhas handled this); directly compiling withnode-gypproduces Node ABI, which Electron cannot load. - electron-rebuild requires Python 3.11 (including distutils); if using 3.12+ you will get
ModuleNotFoundError: No module named 'distutils', the script has specified/opt/homebrew/bin/python3.11, modify as needed.
This project is open-sourced under the MIT License, see LICENSE for details.
This project is a local-first desktop application. The vast majority of data is processed only on your device and will not be uploaded to any server. See PRIVACY.md for details.
Core Principles:
- Microphone recording: Local offline recognition (Whisper.cpp), immediately deleted after recognition
- Chat records: Only stored in memory, automatically cleared after app closes
- Playlist: Only saves song names and local file paths, does not include audio content
- LLM conversation: Only when you actively send a message, the message content will be sent to your configured LLM service
If you discover a security vulnerability, please report it privately via GitHub Security Advisories, do not disclose it in public Issues. See SECURITY.md for details.
The 3D models used in the project have their respective licenses:
- Built-in models (avatar.glb, avatar-avaturn.glb, avatar.vrm): See their respective source licenses
- Firefly Maid model (fireflyMaid.vrm): Third-party VRoid creation, license is OnlyAuthor + redistribution=disallow
- Only the author can commercially use / redistribute
- Please do not embed on other sites or anonymously publicly distribute bare links
- Model files are not included in the GitHub repository
- Production environment URL is configured via
VITE_FIREFLY_VRM_PROD_URLin.env
For the source, author, and license information of all third-party materials (3D models, ASR/TTS models, open-source libraries) used in this project, see CREDITS.md.
If the model license requires "complete credits must be attached", please ensure this file is included when distributing.
English | δΈζ