npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@inworld/tts

v1.1.1

Published

Inworld TTS SDK – generate, stream, and voice management

Readme

@inworld/tts

npm version License: MIT Node.js ≥18

Node.js and browser SDK for the Inworld TTS API — generate, stream, and manage voices.

API Reference · Changelog · Platform


Install

npm install @inworld/tts

Supports ESM, CommonJS, and browser (Vite, webpack 5, Rollup, esbuild).


Authentication

Pass your API key directly or set INWORLD_API_KEY in your environment:

import { InworldTTS } from '@inworld/tts'; // TypeScript: types are bundled, no @types/ needed

const tts = InworldTTS();                       // reads INWORLD_API_KEY from env
const tts = InworldTTS({ apiKey: 'your_key' }); // or pass directly

Get your key at platform.inworld.ai. For browser usage with JWT, see Browser.


Quickstart

import { InworldTTS } from '@inworld/tts';

const tts = InworldTTS();
await tts.generate({ text: 'Hello, world!', voice: 'Dennis', outputFile: 'hello.mp3' });

Models

| Model ID | Quality | Default for | |----------|---------|-------------| | inworld-tts-1.5-max | Higher quality | generate() | | inworld-tts-1.5-mini | Budget option | stream() |

Use max when quality is the priority (e.g. audiobooks, voiceovers). Use mini when cost efficiency matters.


Constructor

const tts = InworldTTS({
  apiKey: 'your_key',           // or set INWORLD_API_KEY env var
  timeout: 120_000,             // HTTP timeout in ms (default: per-method)
  maxConcurrentRequests: 4,     // parallel chunk requests for long text (default: 2)
  maxRetries: 2,                // retry on network errors / 5xx with exponential backoff (default: 2)
  debug: true,                  // log timing and retry info
});

See Constructor in the API Reference for full parameter details and per-method timeout defaults.


generate()

Synthesize speech from text of any length. Blocks until all audio is ready.

// Save to file
await tts.generate({ text: 'Hello!', voice: 'Dennis', outputFile: 'hello.mp3' });

// Get bytes for further processing
const audio = await tts.generate({ text: 'Hello!', voice: 'Dennis' });

// Generate, save, and play
await tts.generate({ text: 'Hello!', voice: 'Dennis', outputFile: 'hello.mp3', play: true });

stream()

Streaming — first audio chunk arrives faster than generate(). Max 2000 characters per call.

for await (const chunk of tts.stream({ text: 'Hello, world!', voice: 'Dennis' })) {
  // chunk is Uint8Array — pipe to audio player or accumulate
}

Timestamps

generateWithTimestamps() and streamWithTimestamps() return word- or character-level timing alongside audio.

const { audio, timestamps } = await tts.generateWithTimestamps({
  text: 'Hello, world!',
  voice: 'Dennis',
  timestampType: 'WORD',
});
const wa = timestamps.wordAlignment;
wa.words.forEach((w, i) =>
  console.log(`${w}: ${wa.wordStartTimeSeconds[i].toFixed(2)}s – ${wa.wordEndTimeSeconds[i].toFixed(2)}s`)
);

See generateWithTimestamps() and streamWithTimestamps() for full details.

play()

Play audio from a Uint8Array or file path. Encoding is auto-detected from magic bytes or file extension.

const audio = await tts.generate({ text: 'Hello!', voice: 'Dennis' });
await tts.play(audio);

await tts.play('hello.mp3');                        // file path also accepted (Node.js only)
await tts.play(pcmBytes, { encoding: 'PCM' });      // encoding hint for raw PCM/ALAW/MULAW

See play() for platform player details and browser constraints.


listVoices()

List voices in your workspace, with optional language filter.

const voices = await tts.listVoices();
const enVoices = await tts.listVoices({ lang: 'EN_US' });
const multi = await tts.listVoices({ lang: ['EN_US', 'ES_ES'] });

getVoice()

Get details of a specific voice.

const voice = await tts.getVoice('workspace__my_clone');

updateVoice()

Update a voice's display name, description, or tags.

await tts.updateVoice({ voice: 'workspace__my_clone', displayName: 'Narrator', tags: ['calm'] });

deleteVoice()

Delete a voice from your workspace.

await tts.deleteVoice('workspace__my_clone');

cloneVoice()

Clone a voice from one or more audio recordings (WAV/MP3). Accepts Uint8Array buffers or file path strings (Node.js only).

const result = await tts.cloneVoice({
  audioSamples: ['sample.wav'],
  displayName: 'My Clone',
});
const voiceId = result.voice.voiceId;

Note: Voice cloning is a long-running operation (up to 5 min). If it times out, check listVoices() — the voice may have been created anyway.

designVoice()

Design a voice from a text description — no recording needed.

const result = await tts.designVoice({
  designPrompt: 'A warm, friendly narrator',
  previewText: 'Hello, welcome to our audiobook.',
});
const preview = result.previewVoices[0];

publishVoice()

Publish a designed or cloned voice preview to your library.

await tts.publishVoice({ voice: preview.voiceId, displayName: 'My Custom Voice' });

migrateFromElevenLabs()

Migrate a voice from ElevenLabs to your Inworld workspace. No ElevenLabs SDK required.

Note: Only voices you own in ElevenLabs can be migrated.

const result = await tts.migrateFromElevenLabs({
  elevenLabsApiKey: 'el_...',
  elevenLabsVoiceId: 'abc123',
});
console.log(`${result.elevenLabsName} → ${result.inworldVoiceId}`);

See Voice Management in the API Reference for all parameters.


Errors

| Class | When | |-------|------| | MissingApiKeyError | No API key or token found at construction | | ApiError | API returned 4xx/5xx — has .code and .details | | NetworkError | Connection or timeout failure |

All inherit from InworldTTSError.

import { InworldTTS, ApiError, MissingApiKeyError, NetworkError } from '@inworld/tts';

try {
  const audio = await tts.generate({ text: 'Hello!', voice: 'Dennis' });
} catch (err) {
  if (err instanceof MissingApiKeyError) console.error('Missing API key');
  else if (err instanceof ApiError) console.error(`HTTP ${err.code}: ${err.message}`);
  else if (err instanceof NetworkError) console.error(`Network error: ${err.message}`);
  else throw err;
}

Browser

For browser usage, use a short-lived JWT token from your backend instead of exposing your API key.

const fetchToken = async () => {
  const { token } = await fetch('/api/tts-token').then(r => r.json());
  return token;
};

const tts = InworldTTS({
  token: await fetchToken(),
  onTokenExpiring: fetchToken, // called automatically when token is about to expire
});

// play() must be called inside a user event handler (browser autoplay policy)
button.onclick = async () => {
  const audio = await tts.generate({ text: 'Hello!', voice: 'Dennis', encoding: 'MP3' });
  await tts.play(audio);
};

For development only, you can use an API key directly with dangerouslyAllowBrowser: true — but your key will be visible in DevTools and billed to your account.

A complete working example is in examples/browser/.

Encoding in browser: Prefer encoding: 'MP3' — supported natively in all browsers. OGG_OPUS/FLAC work in Chrome and Firefox but not Safari. LINEAR16, PCM, ALAW, MULAW cannot be played by play() in browser.


Examples

Runnable examples are in the examples/ directory:

| File | What it shows | |------|---------------| | hello_world.js | Text → MP3 in 3 lines | | stream_audio.js | Real-time streaming | | list_voices.js | List all voices with optional language filter | | clone_voice.js | Clone a voice from a WAV/MP3 recording | | design_voice.js | Design a voice from a text description, preview, and publish | | generate_timestamps.js | Word-level timestamps | | examples/browser/ | Browser usage with JWT auth |


Troubleshooting

MissingApiKeyError / ApiError 401

Set INWORLD_API_KEY or pass apiKey directly. If the key is set but rejected, regenerate it at platform.inworld.ai.

play() blocked by browser (autoplay policy)

Move play() inside a user event handler:

button.onclick = async () => await tts.play(audio);

ApiError: text exceeds 2000 character limit

stream() accepts at most 2000 characters per call. Use generate() instead — it handles any text length automatically.

NetworkError: Request timed out

Increase the timeout or add retries:

const tts = InworldTTS({ timeout: 120_000, maxRetries: 3 });

require('@inworld/tts') throws ERR_REQUIRE_ESM

Both ESM and CommonJS are supported. Ensure you are on Node.js ≥18 and using a bundler that respects the exports field (webpack 5, Vite, Rollup, esbuild).

// ESM
import { InworldTTS } from '@inworld/tts';

// CommonJS
const { InworldTTS } = require('@inworld/tts');

License

MIT