Test TTS & STT models in your browser. No server. No data collection. Powered by WebGPU.
- In-browser inference — models run entirely on your device via WebGPU or WASM
- Zero data collection — your text and audio never leave your browser
- Side-by-side comparisons — compare TTS and STT models head to head
- Model directory — browse, search, and upvote models
- Instant caching — model weights are cached locally after first download
| Layer | Technology |
|---|---|
| Framework | Next.js 16 |
| Styling | Tailwind CSS v4 |
| Database | Neon Postgres + Drizzle ORM |
| Inference | ONNX Runtime Web, kokoro-js, @xenova/transformers |
| Analytics | Vercel Analytics |
| Linter | Biome |
# Clone
git clone https://github.com/MbBrainz/ttslab.git
cd ttslab
# Install dependencies
pnpm install
# Set up environment
cp .env.example .env.local
# Fill in DATABASE_URL and other variables
# Push DB schema & seed
pnpm db:push
pnpm db:seed
# Start dev server (--webpack flag is required for ONNX alias resolution)
pnpm devOpen http://localhost:3000 in a browser with WebGPU support (Chrome 113+, Edge 113+).
src/
├── app/ # Next.js App Router pages & API routes
│ ├── models/ # Model directory & detail pages
│ ├── compare/ # Comparison pages
│ ├── api/ # API routes (upvotes, subscriptions)
│ └── opengraph-image.tsx
├── components/ # React components
│ ├── tts-demo.tsx # TTS playground UI
│ ├── stt-demo.tsx # STT playground UI
│ ├── audio-player.tsx # Reusable audio player
│ └── ui/ # Shared UI primitives
├── lib/
│ ├── db/ # Drizzle schema, queries, types
│ ├── inference/ # Model loaders & registry
│ │ ├── loaders/ # Per-model loader implementations
│ │ └── registry.ts # Lazy loader registry
│ ├── analytics.ts # Vercel Analytics event wrappers
│ └── constants.ts # App-wide constants
└── public/
└── audio-samples/ # Pre-generated audio samples
See CONTRIBUTING.md for development setup, code style, and how to add a model.