{"_id":"@biwills/kittentts","_rev":"2-3cda746aa0e62cc80411fde7662cae01","name":"@biwills/kittentts","dist-tags":{"latest":"1.0.0"},"versions":{"0.0.0-alpha.0":{"name":"@biwills/kittentts","version":"0.0.0-alpha.0","_id":"@biwills/kittentts@0.0.0-alpha.0","maintainers":[{"name":"biwills","email":"ben@biwills.com"}],"dist":{"shasum":"307424345782bafa9177be5a9dcd21f592ded852","tarball":"https://registry.npmjs.org/@biwills/kittentts/-/kittentts-0.0.0-alpha.0.tgz","fileCount":1,"integrity":"sha512-M0MF3tPIsc0a80FVbZPMS16n/1Bfv1ynSxb3a+tApWwnSv0rq/s2przGbwyVTn5VURUJOgGRtTOYDdONLBRAFg==","signatures":[{"sig":"MEUCIQCvFST3lLrD4jC2UrEz5lvZjucDfS2LzFx2bzfWDyZ+tQIgSwy0+nenzPkJGLcCnEcvxkzgYLJJR4fusiZQRi3QQe8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84},"type":"module","_npmUser":{"name":"biwills","email":"ben@biwills.com"},"directories":{},"_nodeVersion":"26.7.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/kittentts_0.0.0-alpha.0_1788199094565_0.5817860024598098","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@biwills/kittentts","version":"1.0.0","description":"Python-free KittenTTS SDK for Node.js, browsers, and React Native","license":"Apache-2.0","publishConfig":{"access":"public","tag":"latest"},"engines":{"node":">=24"},"type":"module","sideEffects":["./dist/browser/worker.js"],"types":"./dist/sdk/index.d.ts","homepage":"https://github.com/biw/kittentts","repository":{"type":"git","url":"git+https://github.com/biw/kittentts.git"},"bugs":{"url":"https://github.com/biw/kittentts/issues"},"packageManager":"pnpm@11.16.0","overrides":{"adm-zip":"0.6.0","protobufjs":"7.6.5"},"keywords":["tts","text-to-speech","onnx","node","browser","react-native","ios","android"],"exports":{".":{"browser":{"types":"./dist/sdk/browser-entry.d.ts","import":"./dist/sdk/browser-entry.js"},"react-native":{"types":"./dist/sdk/react-native-entry.d.ts","import":"./dist/sdk/react-native-entry.js"},"node":{"types":"./dist/sdk/node-entry.d.ts","import":"./dist/sdk/node-entry.js"},"types":"./dist/sdk/index.d.ts","import":"./dist/sdk/node-entry.js"},"./package.json":"./package.json","./audio":{"types":"./dist/audio/index.d.ts","import":"./dist/audio/index.js"},"./audio/mp3":{"types":"./dist/audio/mp3.d.ts","import":"./dist/audio/mp3.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./browser":{"types":"./dist/browser/index.d.ts","import":"./dist/browser/index.js"},"./browser/worker":{"types":"./dist/browser/worker.d.ts","import":"./dist/browser/worker.js"},"./react-native":{"browser":{"types":"./dist/sdk/react-native-web-entry.d.ts","import":"./dist/sdk/react-native-web-entry.js"},"react-native":{"types":"./dist/sdk/react-native-entry.d.ts","import":"./dist/sdk/react-native-entry.js"},"types":"./dist/sdk/react-native-entry.d.ts","import":"./dist/sdk/react-native-entry.js"}},"scripts":{"build":"tsdown","prepublish":"pnpm build","test":"vitest run","test:firefox":"KITTENTTS_FIREFOX=1 vitest run tests-js/firefox.integration.test.ts","test:safari":"KITTENTTS_SAFARI=1 vitest run tests-js/safari.integration.test.ts","test:safari:webgpu":"KITTENTTS_SAFARI=1 KITTENTTS_SAFARI_WEBGPU=1 vitest run tests-js/safari.integration.test.ts","test:react-native":"vitest run tests-js/react-native.test.ts","test:watch":"vitest","example:node":"pnpm build && node examples/node-synthesize.mjs","fixtures:bootstrap":"tsx scripts/bootstrap_reference_fixtures.ts","samples:generate":"tsx scripts/generate_listening_samples.ts .context/listening-samples","serve:browser-harness":"node scripts/serve_fixture_harness.mjs","native:smoke:assets":"tsx scripts/bootstrap_react_native_smoke_assets.ts","native:smoke:prepare":"pnpm build && node scripts/prepare_react_native_smoke.mjs","native:smoke:serve":"node scripts/serve_react_native_smoke_assets.mjs"},"peerDependencies":{"@dr.pogodin/react-native-fs":"2.40.1","onnxruntime-node":"1.27.0","onnxruntime-react-native":"1.24.3","onnxruntime-web":"1.27.0"},"peerDependenciesMeta":{"@dr.pogodin/react-native-fs":{"optional":true},"onnxruntime-node":{"optional":true},"onnxruntime-react-native":{"optional":true},"onnxruntime-web":{"optional":true}},"devDependencies":{"@arethetypeswrong/cli":"^0.18.5","@types/node":"^24.13.3","fflate":"^0.8.3","onnxruntime-node":"1.27.0","onnxruntime-web":"1.27.0","phonemizer":"^1.2.1","publint":"^0.3.21","tsdown":"^0.22.13","tsx":"^4.23.1","typescript":"^6.0.3","vitest":"^4.1.10","wasm-media-encoders":"0.7.0"},"gitHead":"daa320e728bae5a1d1d65112a10abe47d03ae87b","_id":"@biwills/kittentts@1.0.0","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-GHGwUqaS9pjkQoqReneO/CdmbA8Qhgaq9s94YMTk6SF7MuJH9kW80mVNrg6vi7zauT0P0UkHesoeBmtgUAtAoA==","shasum":"c3216ff427abff283f7ae739a5770f83fbecf458","tarball":"https://registry.npmjs.org/@biwills/kittentts/-/kittentts-1.0.0.tgz","fileCount":48,"unpackedSize":3959023,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@biwills%2fkittentts@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDlnwLrntzEyFoqJB/ZAhfxBWDBAvT0B1XJe7y8qUK29AiEA5O2x5r85xBmH5VyG6YOO29GA+vI4vd1E/ruZFeRJz0g="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f3a18beb-998a-41a4-87f6-00d11e4535bc"}},"directories":{},"maintainers":[{"name":"biwills","email":"ben@biwills.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/kittentts_1.0.0_1788387186315_0.8656302283888158"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-31T17:58:14.349Z","modified":"2026-09-02T22:13:06.883Z","0.0.0-alpha.0":"2026-08-31T17:58:14.691Z","1.0.0":"2026-09-02T22:13:06.558Z"},"maintainers":[{"name":"biwills","email":"ben@biwills.com"}],"readme":"# KittenTTS\n\nIsomorphic text-to-speech for Node.js, browsers, and React Native. One TypeScript API, backed by ONNX Runtime, with no Python, eSpeak, or system codecs required to install or run.\n\n`@biwills/kittentts` is designed to match the upstream\n[KittenML/KittenTTS](https://github.com/KittenML/KittenTTS) Python\nimplementation, verified against its output, but universal: Node, browser, and\nReact Native share one package and one API instead of a separate library per\nplatform.\n\n```ts\nimport { KittenTTS } from \"@biwills/kittentts\";\n\nconst tts = await KittenTTS.create({ model: \"nano\" });\nconst result = await tts.generate(\"KittenTTS runs without Python.\", { voice: \"Bella\" });\nawait writeFile(\"speech.wav\", result.wavData());\nawait tts.dispose();\n```\n\n## Highlights\n\n- **One API, every JavaScript target.** Node 24 native inference, browser WASM\n  and WebGPU, Web Workers, and native iOS and Android.\n- **Four models.** `nano`, `nano-int8`, `micro`, and `mini`, downloaded lazily\n  from pinned Hugging Face revisions and verified against SHA-256 digests.\n- **Streaming.** Demand-driven chunks with backpressure and `AbortSignal`\n  cancellation.\n- **Audio output.** WAV, base64 WAV, lazy MP3, token timings, and playback\n  adapters for Web Audio, Expo Audio, and React Native Sound.\n- **Durable caches.** Atomic, integrity-checked model caches that recover from\n  corruption and work fully offline once warm.\n- **Zero production dependencies.** Platform runtimes are optional peers, so\n  each app installs only what it needs.\n\n## Install\n\nPick the runtime for your target. All three are optional peers.\n\n```bash\n# Node.js 24+\nnpm install @biwills/kittentts onnxruntime-node\n\n# Browsers\nnpm install @biwills/kittentts onnxruntime-web\n\n# React Native (bare or Expo development build)\nnpm install @biwills/kittentts onnxruntime-react-native @dr.pogodin/react-native-fs\n```\n\nExpo Go is not supported because ONNX Runtime and the filesystem module are native. See the [React Native guide](docs/react-native.md) for Expo setup, playback, cancellation, caching, and preloaded assets.\n\nThe package is ESM-only and targets ES2022. CommonJS callers must use dynamic `import()`.\n\n## Usage\n\n### Node.js\n\n```ts\nimport { writeFile } from \"node:fs/promises\";\nimport { KittenTTS } from \"@biwills/kittentts\";\n\nconst tts = await KittenTTS.create({\n  model: \"nano\",\n  defaultVoice: \"Bella\",\n});\n\ntry {\n  const result = await tts.generate(\"Hello from Node.\");\n  console.log(result.durationSeconds, result.sampleRate);\n  await writeFile(\"hello.wav\", result.wavData());\n} finally {\n  await tts.dispose();\n}\n```\n\n### Browser\n\nThe browser build defaults to a module worker and to `executionMode: \"auto\"`, which prefers WebGPU and falls back to WASM.\n\n```ts\nimport { KittenTTS } from \"@biwills/kittentts\";\n\nconst tts = await KittenTTS.create({\n  model: \"nano-int8\",\n  onProgress: (event) => console.log(event.phase, event.progress),\n});\n\nawait tts.speak(\"Hello from the browser.\"); // call from a user gesture\n```\n\nPass `transport: \"direct\"` for main-thread inference, or `executionMode: \"webgpu\"` to fail fast when WebGPU is unavailable. Check `tts.capabilities()` for the provider, thread count, and cross-origin isolation actually in use.\n\n### React Native\n\n```ts\nimport * as ExpoAudio from \"expo-audio\";\nimport { KittenTTS, createExpoAudioPlayer } from \"@biwills/kittentts/react-native\";\n\nconst tts = await KittenTTS.create({\n  model: \"nano-int8\",\n  player: createExpoAudioPlayer(ExpoAudio),\n});\n\nawait tts.speak(\"Hello from this device.\");\nawait tts.dispose();\n```\n\n### Streaming\n\n```ts\nconst controller = new AbortController();\n\nfor await (const chunk of tts.generateStream(longDocument, {\n  voice: \"Bruno\",\n  signal: controller.signal,\n})) {\n  play(chunk.result.audio, chunk.result.sampleRate);\n  if (chunk.isLast) break;\n}\n```\n\nEach `next()` synthesizes exactly one text chunk, so consumers control the pace and nothing queues unbounded. `collectKittenTtsStream()` joins a stream into a single result with optional crossfade.\n\nThe [JavaScript SDK guide](docs/javascript-sdk.md) covers MP3 output, token timings, progress events, cache controls, worker and ONNX module URLs, and the lower-level entrypoints.\n\n## Models\n\n| Model | Parameters | Precision | First download |\n| --- | ---: | --- | ---: |\n| `nano` | 15M | fp32 | ~60 MB |\n| `nano-int8` | 15M | int8 | ~28 MB |\n| `micro` | 40M | fp32 | ~45 MB |\n| `mini` | 80M | fp32 | ~82 MB |\n\nSizes include the shared voice archive. Assets come from pinned [KittenML](https://huggingface.co/KittenML) Hugging Face revisions and are not embedded in the npm tarball. Bundled voices include Bella, Bruno, Hugo, Jasper, Kiki, Leo, Luna, and Rosie.\n\nThe phonemizer targets `en-us`. Non-English and malformed input is handled safely and deterministically, but pronunciation accuracy outside English is not a supported claim.\n\n## Platform Support\n\n| Runtime | Direct | Worker | WASM | WebGPU | Verified in CI |\n| --- | --- | --- | --- | --- | --- |\n| Node.js 24 | Yes | N/A | N/A | N/A | Linux, macOS, Windows |\n| Chrome (current) | Yes | Yes | Yes | Yes | Yes |\n| Firefox (current) | Yes | Yes | Yes | Not claimed | Yes |\n| Safari 26.5+ | Yes | Yes | Yes | Yes | WASM in CI, WebGPU on hardware |\n| React Native 0.81.x, iOS 15.1+ | Yes | N/A | N/A | N/A | Release simulator smoke |\n| React Native 0.81.x, Android API 24+ | Yes | N/A | N/A | N/A | Release emulator smoke |\n| React Native Web | Yes | Yes | Yes | Browser-dependent | Browser CI |\n\nBrowser WASM runs on one thread unless the page is cross-origin isolated with\n`Cross-Origin-Opener-Policy: same-origin` and\n`Cross-Origin-Embedder-Policy: require-corp`.\n\nReact Native 0.82 and newer are blocked on a bridge-free release of the pinned\n`onnxruntime-react-native` peer. CI runs real native inference in Release-mode\nHermes apps on iOS Simulator and Android Emulator. Performance and memory on\nspecific physical devices remain application-level validation.\n\n## Package Entrypoints\n\n| Import | Purpose |\n| --- | --- |\n| `@biwills/kittentts` | High-level facade, resolved per platform through package conditions |\n| `@biwills/kittentts/node` | Node runtime and cache controls |\n| `@biwills/kittentts/browser` | Browser runtime, playback, and worker client |\n| `@biwills/kittentts/browser/worker` | Standalone worker entrypoint |\n| `@biwills/kittentts/react-native` | Native runtime, cache controls, and playback adapters (browser facade under React Native Web) |\n| `@biwills/kittentts/audio` | WAV encoding and audio joining |\n| `@biwills/kittentts/audio/mp3` | Lazy MP3 encoder |\n\n## Relationship to KittenML\n\nThis is an independent TypeScript SDK that consumes KittenML's published ONNX\nmodels and reproduces the behavior of the Python reference: the same\npreprocessing, phonemization, chunking, and audio output, checked in CI against\na Python-generated golden corpus. It is a separate package from, and does not\ndepend on, these upstream projects:\n\n- [KittenML/KittenTTS](https://github.com/KittenML/KittenTTS), the Python\n  reference implementation used for parity fixtures\n- [KittenML/KittenTTS-web](https://github.com/KittenML/KittenTTS-web),\n  published as `@kittentts/web`\n- [KittenML/KittenTTS-react-native](https://github.com/KittenML/KittenTTS-react-native),\n  published as `@kittentts/react-native`\n\n## License\n\nApache-2.0. Model repositories have their own terms and are not redistributed by this package.\n","readmeFilename":"README.md","description":"Python-free KittenTTS SDK for Node.js, browsers, and React Native","homepage":"https://github.com/biw/kittentts","keywords":["tts","text-to-speech","onnx","node","browser","react-native","ios","android"],"repository":{"type":"git","url":"git+https://github.com/biw/kittentts.git"},"bugs":{"url":"https://github.com/biw/kittentts/issues"},"license":"Apache-2.0"}