FAQ
Why can't I run this in Expo Go?
Expo Go ships a fixed set of native modules and cannot load arbitrary native code. This SDK depends on ONNX Runtime, which is native. You need a Development Build (npx expo run:ios / npx expo run:android). There is no configuration that makes Expo Go work.
I get a 401 or 403 when installing
Your npm token is missing, expired, or not authorized for the @optimalai scope. Check these in order:
- Your npm username is on the
sdk-beta-readersteam. - Your token is a granular read-only token that includes the
@optimalaiscope. NPM_TOKENis exported in the shell or configured as a secret in CI/EAS..npmrccontains${NPM_TOKEN}— not a literal token, and not a stale one.
The CLI fails with "base URL not configured"
The production model CDN URL is injected by OptimalAI at release time, and the npm package contains no placeholder domain. Until it is live, pass one explicitly:
npx @optimalai/model-tools@beta add kokoro-82m-v1.1-zh-int8 \
--base-url https://your-staging-hostor set OPTIMALAI_MODELS_BASE_URL.
load() throws MODEL_NOT_FOUND
Usually a Metro or asset-resolution problem, not a missing model:
- Did you wrap the Metro config with
withOptimalAI? Without it,.onnx,.bin, and.txtare not registered as assets. - Did you re-run the model installer after a clean checkout? Model files are build artifacts and are not committed.
- Did you rebuild the Development Build after changing native dependencies?
- Is the generated
optimalai-models.tspresent and imported?
load() throws MODEL_CORRUPT
An asset resolved but failed byte-length or hash validation. The file on disk is not the file the manifest describes — a truncated download or a partially deleted directory. Remove the model directory and reinstall:
npx @optimalai/model-tools@beta add kokoro-82m-v1.1-zh-int8The CLI refuses to overwrite a directory that fails verification on purpose, so you have to clear it yourself.
I get BUSY
A load or synthesis is already running on that client. The SDK allows one at a time. Await the in-flight call, then retry. To run work in parallel you need more than one client — each with its own model load and its own memory cost.
My English text fails with INVALID_TEXT
The word is not in the bundled lexicon, and there is no eSpeak fallback in the Beta. This is deliberate. Test your actual content against the lexicon early, and sanitize user input before synthesizing it. See Error handling.
Can I change the voice without reloading the model?
Yes. Pass a different voiceId to synthesizeToFile. The ONNX session stays loaded; only the style embedding changes. See Voices & speed.
Where does the WAV go, and who deletes it?
By default it lands in the app's cache directory with a generated name. If you want a specific location, pass outputPath. Either way, you own the file — the SDK never deletes it. Clean up your own directory if you synthesize repeatedly.
What happens if I pass an outputPath that already exists?
Synthesis fails with OUTPUT_EXISTS. Delete the file first, or let the SDK generate a fresh name. Passing the same path twice will not silently overwrite.
Is there a streaming API?
No. Not in this Beta, and not on the immediate roadmap.
Can I use this with bare React Native, without Expo?
No. The Beta targets Expo SDK 57 specifically. Bare React Native support is not part of this release.
How do I report a problem?
Include the error code, the TtsError.details payload, your device and OS version, and the model id. That is usually enough to reproduce.