calesthio/kokoro-tts
>- Local and self-hosted text-to-speech with Kokoro, the ~82M-parameter open-weight (Apache 2.0) model by hexgrad. Use when synthesizing speech offline, on-device, in the browser, or on your own server without per-character API cost — for high-volume narration, audiobooks, privacy-constrained pipelines, and prototyping. Covers running Kokoro via the Python `kokoro` package, ONNX / kokoro-js in the browser, and the OpenAI-compatible Kokoro-FastAPI wrapper; picking voices and language codes; blending voices; chunking long text; controlling pronunciation via misaki/espeak-ng; and judging when Kokoro is the right tool versus when its lack of voice cloning, narrow emotional range, and weaker non-English quality mean you should reach for a hosted or larger model instead. Not for voice cloning, expressive/emotional character performance, or high-fidelity multilingual work — say so and route elsewhere.
npx skills add https://github.com/calesthio/generative-media-skills --skill kokoro-tts
Kokoro is a small, fast, permissively licensed text-to-speech model. Its entire
value proposition is that you run it yourself: no API key, no per-character billing,
no audio leaving your machine. This skill helps an agent decide whether Kokoro fits a
job, run it through the right runtime, and get acceptable output — and, just as
importantly, recognize the jobs where Kokoro will disappoint the user and something
else is the correct answer.
All version, license, voice-count, ranking, and performance facts below were verified
on 2026-07-10 against the sources listed at the end. Treat them as volatile.
with an ISTFTNet decoder (arXiv 2203.02395). The card describes it as
"Decoder only: no diffusion, no encoder release." Source: hexgrad/Kokoro-82M model card.
fp32 on 2024-12-25; v1.0 released 2025-01-27 and is the current default.
Because weights are Apache-2.0 you may deploy commercially, redistribute, and
fine-tune (subject to attribution). Source: model card.
on permissive / non-copyrighted material: public-domain audio, Apache/MIT-licensed
content, and synthetic audio generated by closed TTS models, plus <1 hr from
Koniwa (CC BY 3.0) and <11 hrs from SIWIS (CC BY 4.0). Reported training cost ≈ $1000
(~1000 A100-80GB GPU-hours). The heavy reliance on synthetic data is the root cause of
Kokoro's flat prosody and its uneven non-English quality — keep it in mind. Source: model card.
as one language). Sources: model card, VOICES.md.
Reach for Kokoro when:
voiceover, batch document-to-speech, screen readers). Marginal cost is electricity.
air-gapped — and no text may be sent to a cloud API.
paid provider.
Do NOT use Kokoro (and tell the user so) when the job needs:
zero-shot cloning. The encoder was deliberately not released. You cannot clone a
reference voice. Route to a cloning-capable provider.
delivery. Kokoro has no emotion/style tokens and a narrow prosodic range; output is
competent but flat. Fine for a neutral narrator, wrong for a video-game character.
C/D-graded and trained on little data (see quality grades below); several languages
also truncate long text. English is the only tier-1 language.
personality.** Kokoro is a batch/streaming *synthesizer*, not a dialog voice.
If the request is voice cloning or emotional VO, do not try to fake it with blending or
prompt tricks — state the limitation plainly and suggest a cloning/expressive provider.
Voice IDs follow [langprefix][gender]_[name], e.g. af_heart = American Female
"Heart", bm_george = British Male "George", if_sara = Italian Female "Sara".
Language codes (pass as lang_code in Python; aliases en-us→a, en-gb→b):
| code | language | code | language |
|------|----------|------|----------|
| a | American English | i | Italian |
| b | British English | j | Japanese |
| e | Spanish | p | Brazilian Portuguese |
| f | French | z | Mandarin Chinese |
| h | Hindi | | |
Source: VOICES.md.
Quality is not uniform — pick by grade, not by name. VOICES.md assigns each voice an
"Overall" grade combining a target-quality letter and how much training audio it received
(more audio = higher grade). Documented highlights (verified 2026-07-10):
af_heart (grade A, the card's default), af_bella (A−),af_nicole (B−, breathy/ASMR), bf_emma (B−, British).
af_aoede, af_kore, af_sarah, am_fenrir, am_michael,am_puck (all C+). bm_fable, bm_george (C, British male).
am_adam (F+),af_jessica / af_river (D). Most non-English voices are C/D, trained on ~minutes of
synthetic data.
Production heuristic: default to af_heart (lang a). For a project the user should
audition 3–4 A/B-graded voices before committing — grades predict, they do not guarantee,
per-sentence quality.
Documented limit: Kokoro processes at most 510 phonemized tokens per forward pass
(512 with boundary tokens). VOICES.md notes voices "perform best on a goldilocks range of
100–200 tokens," are weak on very short utterances (<10–20 tokens), and **rush on long
ones (>400)**. Source: model card / VOICES.md.
Consequences for production:
KPipeline splits automatically; its split_pattern defaults to r'\n+'for English and returns one (graphemes, phonemes, audio) result per chunk, which you
concatenate. Source: pipeline.py.
truncated unless you pre-split it yourself (insert \n at sentence boundaries).
This is a common silent-failure trap — verify non-English output length.
boundaries (≈ one to three sentences), synthesize each, and concatenate with a short
silence pad. Kokoro-FastAPI's defaults (~175 target / 250 / 450 absolute max tokens)
are a reasonable starting point if you build your own splitter.
Kokoro does not read graphemes directly — text is converted to phonemes by
misaki, hexgrad's G2P library, then fed to the
model. English uses misaki's dictionary (spaCy + num2words). **Out-of-dictionary words
fall back to espeak-ng** (EspeakFallback, on by default); espeak-ng is also the backbone
for non-English G2P. Install espeak-ng as a system dependency or OOV words degrade to
letter-by-letter spelling. Documented example: with fallback, eBook → ˈi bˈʊk; without
it, → ˈiː bˈi ˈoʊ ˈoʊ kˈeɪ (spelled out). Source: misaki README.
To fix a mispronounced word (proper noun, brand, acronym, number read wrong):
word, e.g. Misaki or Kokoro. Put the
IPA/Kokoro phonemes between the slashes; stress marks like ˈ matter.
phonemes directly to the model so a batch job stays consistent.
overkill.
Heuristic: always dry-run domain jargon, names, and numbers before a long batch —
these are Kokoro's most common error class, and each is a one-line phoneme fix.
A Kokoro "voice" is a style vector (voicepack tensor). Blending is a **weighted average
of two style vectors**, which produces a new usable voice. The documented mechanism is a
weighted numpy add, style1*(w0/100) + style2*(w1/100), with weights normalized if they
don't sum to 100; several tools cap blending at exactly two voices. Source:
nazdridoy/kokoro-tts voice-blending docs.
voice="af_sky+af_bella"(equal), or weighted per that server's syntax. Source:
full control (any ratio; nothing forces a 2-voice cap if you write the math).
Use blending to: nudge timbre/pitch between two graded voices, or build a house voice
that isn't any single shipped one. It does not add emotion, create a new speaker
identity from a reference, or rescue a low-grade voice — averaging two C-grade voices
yields a C-grade blend.
kokoro package (default for servers/batch)Best for narration pipelines, audiobooks, and anything on your own box. PyTorch backend;
GPU optional. Example (labeled example — adapt paths/voices):
# pip install kokoro>=0.9.2 soundfile ; plus system espeak-ng
from kokoro import KPipeline
import soundfile as sf
import numpy as np
pipeline = KPipeline(lang_code='a') # 'a' = American English
text = "The quarterly report is ready.\nRevenue rose twelve percent."
chunks = []
for graphemes, phonemes, audio in pipeline(text, voice='af_heart', speed=1.0):
chunks.append(audio) # one result per split (default r'\n+')
sf.write('out.wav', np.concatenate(chunks), 24000) # 24 kHz mono
Why structured this way: KPipeline does G2P + chunking + inference; iterating yields per-chunk
audio you concatenate, which is exactly the long-form pattern above. speed (~0.8–1.3)
trades pace for naturalness. For lower-level control, KModel runs a single already-phonemized
chunk. Source: model card, Python API.
Runs 100% client-side via Transformers.js — no server, nothing uploaded. Model id
onnx-community/Kokoro-82M-v1.0-ONNX. Example (labeled example):
// npm i kokoro-js
import { KokoroTTS, TextSplitterStream } from "kokoro-js";
const tts = await KokoroTTS.from_pretrained("onnx-community/Kokoro-82M-v1.0-ONNX", {
dtype: "q8", // "fp32" | "fp16" | "q8" | "q4" | "q4f16"
device: "webgpu", // "wasm" | "webgpu" in-browser, "cpu" in Node ; use fp32 with webgpu
});
const audio = await tts.generate("Hello from the browser.", { voice: "af_heart" });
audio.save("audio.wav"); // tts.list_voices() lists all IDs
// Streaming: push tokens, get audio incrementally
const splitter = new TextSplitterStream();
const stream = tts.stream(splitter);
(async () => { for await (const { text, phonemes, audio } of stream) audio.save("chunk.wav"); })();
Quantization trade-off: q8/q4 shrink download and speed WASM at some quality cost;
fp32 is highest quality and is recommended with WebGPU. Source:
onnx-community/Kokoro-82M-v1.0-ONNX.
For non-JS ONNX use, kokoro-onnx (Python) runs on onnxruntime (CPU) or
onnxruntime-gpu (CUDA) and is what enables Raspberry-Pi / edge deployments.
The fastest way to give an existing app a local TTS backend: a Dockerized wrapper exposing
an OpenAI-compatible /v1/audio/speech endpoint, so any client written for OpenAI TTS
works by changing the base URL. Supports voice mixing (af_sky+af_bella), MP3/WAV/Opus/FLAC/M4A/PCM,
streaming, per-word timestamps, a phoneme endpoint, and CPU/NVIDIA/AMD images. Example
(labeled example):
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8880/v1", api_key="not-needed")
client.audio.speech.create(
model="kokoro", voice="af_heart", input="Local TTS, OpenAI-shaped API.",
response_format="mp3",
).stream_to_file("out.mp3")
Source: remsky/Kokoro-FastAPI. Note it is a
third-party wrapper (Apache-2.0-licensed model, separate project) — pin a version and
verify its endpoint/voice-mixing syntax against its current README, as it evolves.
Hosted endpoints. Several inference platforms (e.g. Replicate, Baseten, and others)
host Kokoro if you want the model's economics without self-hosting; those reintroduce a
per-use cost and send text off-box, so they undercut the two main reasons to choose Kokoro.
Prefer them only for burst capacity or when you can't run the model locally.
RTF (real-time factor) definitions differ between sources — some report
audio-seconds-per-compute-second (higher = faster), others the inverse. Read the units.
chunked ≤510 tokens) reports ~96× RTF on an A10G, ~81× on L4, ~36× on T4; ONNX ran
lower (20–37×). Source: Kokoro v1 benchmark gist, retrieved 2026-07-10.
shows ~5× RTF on a 32-vCPU instance; another reports RTF ≈ 0.45–0.51 (i.e. ~2×
real-time) on 4 cores. Source: gist above and a 4-core AMD EPYC run, retrieved 2026-07-10.
suffices for inference (8 GB+ for comfortable batching). Runs on modest hardware and
Raspberry-Pi-class devices via ONNX.
Heuristic: for real-time or streaming UX, prefer GPU or a strong multi-core CPU;
low-core/edge CPUs work for batch/offline but may fall near or below real-time on long text.
Quantized ONNX (q8/q4) helps on constrained CPU/WASM at a quality cost.
TTS Spaces Arena** in the weeks around its release. This was a limited-model / single-voice
Arena setting — strong signal for its size, not a claim of beating all commercial models.
Source: model card.
open-weight models. As of ~2026-03, one aggregated leaderboard placed **Kokoro-82M v1.0
~4th among open-weight** models (Elo ≈ 1060), with newer/larger open models (e.g. Step
Audio EditX, Elo ≈ 1118) ahead. Secondary source, retrieved 2026-07-10:
TTS Arena / Artificial Analysis.
Honest framing for a user: Kokoro is exceptional *for 82M parameters and $0 marginal
cost*, competitive with far larger models on neutral English narration, and clearly behind
frontier commercial and larger open models on expressiveness, cloning, and multilingual
fidelity. Sell it on economics, privacy, and footprint — not on being the highest-quality
voice available.
Before shipping Kokoro audio, listen for:
\n.lang_code to the voice's prefix(a/b voices with English text, etc.); mismatches sound off.
different model, not more retries.
permitted with attribution. Verify the license of any *wrapper* (e.g. Kokoro-FastAPI)
separately; they are distinct projects. (Verified 2026-07-10.)
This is documented and the released data (Koniwa CC BY 3.0, SIWIS CC BY 4.0) is
permissively licensed, but if a client has strict provenance requirements, disclose it.
impersonate a *style* or produce misleading audio. Don't generate audio that
impersonates a real, identifiable person or is designed to deceive; disclose synthetic
voice where the audience could reasonably assume it's human.
labels, not consenting individuals, so there's no per-speaker consent issue; the general
synthetic-media disclosure norm still applies.
Take calesthio/kokoro-tts from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference pip, npm.
Without those the skill loads but fails at the first command.