Technology Stack Documentation
June 9, 2025 ยท View on GitHub
Overview
This document outlines the technology choices for the real-time transcription system, focusing on Node.js-based solutions to minimize language diversity while maintaining production quality.
Core Technologies
Language: Node.js (v20.x)
- Rationale: Single language for entire application, excellent async support for real-time processing
- Runtime: Docker containerized for consistent deployment
Audio Pipeline
Audio Capture: PipeWire
- Library: Direct PipeWire access via child_process
- Alternative: PulseAudio compatibility layer for broader support
- Format: 16kHz, mono, PCM WAV format for Whisper compatibility
Voice Activity Detection (VAD)
- Primary: Custom energy-based VAD implementation
- Rationale: Silero VAD has limited Node.js support
- Features:
- Energy threshold detection
- Adaptive noise floor
- Speech onset/offset detection with configurable delays
Audio Processing: node-wav
- Version: Latest stable
- Features: Fast WAV encoding/decoding, Float32Array support
- Performance: 750x faster than alternatives
Transcription Services
Primary: OpenAI Whisper API
- Library: openai (official SDK)
- Model: whisper-1
- Format: WAV files (1-3 second chunks)
- Error Handling: Automatic retry with exponential backoff
Fallback: whisper.cpp
- Integration: Direct CLI execution via child_process
- Models: base.en (fast) and small.en (accurate)
- Benefits: No complex bindings, proven stability
Text Output
Wayland Integration: wtype
- Method: Child process execution
- Features: Unicode support, proper timing simulation
- Security: Runs with minimal privileges
Container Stack
Base Image: node:20-slim
- Size: Minimal footprint (~150MB)
- Dependencies: Only essential audio/Wayland tools
Audio Access
# Mount points
/run/user/1000/pipewire-0:/tmp/pipewire-0
/dev/snd:/dev/snd # Fallback ALSA access
Wayland Access
# Environment and sockets
$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY
Architecture Decisions
Monolithic Container
- Rationale: Simplified deployment, reduced inter-service communication
- Structure: Single Node.js process with worker threads for audio processing
VAD Implementation
Due to limited Node.js support for Silero VAD, we implement a custom solution:
class EnergyBasedVAD {
constructor(options = {}) {
this.energyThreshold = options.threshold || 0.01;
this.speechStartDelay = options.startDelay || 300; // ms
this.speechEndDelay = options.endDelay || 1000; // ms
}
processAudioFrame(frame) {
const energy = this.calculateRMS(frame);
return this.detectSpeechState(energy);
}
}
Error Handling Strategy
- Network Failures: Immediate fallback to local whisper.cpp
- Audio Errors: Graceful restart with user notification
- Permission Issues: Clear error messages with fix instructions
Performance Optimizations
- Audio Buffering: Ring buffer for zero-copy audio processing
- Parallel Processing: Transcription runs concurrent to audio capture
- Chunk Overlap: 100ms overlap prevents word cutoff
Security Considerations
Container Isolation
- Non-root user (node:1000)
- Read-only root filesystem
- No network access except OpenAI API
API Key Management
- Environment variable injection
- Never logged or stored in container
- Fallback to local processing if missing
Audio Privacy
- No persistent storage
- Memory-only processing
- Optional local-only mode
Development Guidelines
Code Style
- ES6+ modules
- Async/await for all I/O operations
- Comprehensive error handling
- JSDoc type annotations
Testing Strategy
- Unit tests for VAD logic
- Integration tests with mock audio
- End-to-end tests in container
Monitoring
- Health checks via HTTP endpoint
- Prometheus metrics for performance
- Structured JSON logging
Library Versions
{
"dependencies": {
"openai": "^4.0.0",
"node-wav": "^0.0.2",
"winston": "^3.11.0",
"express": "^4.18.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"jest": "^29.0.0",
"eslint": "^8.0.0"
}
}
Future Considerations
Potential Upgrades
- WebRTC VAD: If Node.js bindings improve
- Streaming Transcription: When OpenAI adds support
- GPU Acceleration: For local whisper.cpp
Scalability Path
- Horizontal Scaling: Multiple container instances
- Queue System: Redis for audio chunk queuing
- Distributed Processing: Kubernetes deployment