Text to Speech in TypeScript
Add text to speech to a TypeScript project by calling the Narakeet REST API. The example on this page uses the built-in fetch with full type annotations — no third-party package or build step required. Node.js 22.6+ runs .ts files natively, so the code works without tsc, Webpack, or any bundler.
See the Text to Speech API reference for authentication, polling, subtitle conversion, and other features common to all languages.
- TypeScript Text to Speech Example
- Running TypeScript Without a Build Step
- TypeScript TTS with Deno and Bun
- Controlling Voice and Audio Settings
- TypeScript TTS Package
TypeScript Text to Speech Example
The following script sends text to the Narakeet API and saves the result as an MP3 file. The textToSpeech function is fully typed and uses AbortSignal.timeout for a 30-second request deadline.
import { writeFile } from 'node:fs/promises';
async function textToSpeech(
apiKey: string,
voice: string,
text: string,
outputPath: string
): Promise<void> {
const response: Response = await fetch(
`https://api.narakeet.com/text-to-speech/mp3?voice=${voice}`,
{
method: 'POST',
headers: {
'Accept': 'application/octet-stream',
'Content-Type': 'text/plain',
'x-api-key': apiKey,
},
body: text,
signal: AbortSignal.timeout(30_000),
},
);
if (!response.ok) {
const errorBody: string = await response.text();
throw new Error(`API error ${response.status}: ${errorBody}`);
}
const buffer: Buffer = Buffer.from(await response.arrayBuffer());
await writeFile(outputPath, buffer);
}
const apiKey: string | undefined = process.env.NARAKEET_API_KEY;
if (!apiKey) {
console.log('Please set NARAKEET_API_KEY environment variable');
process.exit(1);
}
await textToSpeech(apiKey, 'lewis', 'Hi there from TypeScript', 'output.mp3');
console.log('File saved at: output.mp3');
Save this as tts.ts and run with node --experimental-strip-types tts.ts (Node 22.6+). No compilation step, no tsconfig.json, and no package.json required — Node strips the type annotations at runtime.
For the complete project with Docker support, see the TypeScript streaming API example on GitHub.
Running TypeScript Without a Build Step
Node.js 22.6 introduced --experimental-strip-types, which removes TypeScript annotations before execution. This means you can write .ts files with full type safety and run them directly — no tsc, ts-node, tsx, or any bundler in the chain. The flag becomes stable and unflagged in Node 23.6+.
This is ideal for quick scripts, CLI tools, and automation pipelines where adding a TypeScript build step creates unnecessary friction. The types help catch mistakes during development (your editor still type-checks), but the runtime does not need them.
TypeScript TTS with Deno and Bun
The same code runs on other TypeScript-native runtimes with minimal changes:
- Deno — supports
.tsnatively. Replacenode:fs/promiseswithDeno.writeFileand remove theBuffer.fromwrapper, since Deno’sfetchreturns aReadableStreamyou can pipe directly. - Bun — runs
.tsout of the box. The Node.jsfetchandwriteFileAPIs are fully compatible, so the example above works without changes.
The API itself is runtime-agnostic — it accepts a POST with text and returns audio bytes over HTTPS.
Controlling Voice and Audio Settings
The endpoint URL and query parameters control the output:
| Parameter | How to set |
|---|---|
| Audio format | Change the URL path: /text-to-speech/mp3, /text-to-speech/m4a, or /text-to-speech/wav (polling API required for WAV) |
| Voice | Set ?voice=lewis — pick from 900 voices across 100 languages at Text to Speech Voices |
| Speed | Add &voice-speed=1.2 for 20% faster, or &voice-speed=0.85 to slow down |
| Volume | Add &voice-volume=soft or &voice-volume=loud |
For pitch adjustments, sentence pauses, and multi-voice scripts, use the script header format in the request body. Full details at Configuring Audio Tasks.
TypeScript TTS Package
A common question is whether a dedicated TypeScript text to speech npm package exists. With Narakeet, the built-in fetch API handles the entire integration — POST text, receive audio bytes, write to disk. There is no package to install, no type definitions to add, and no SDK to configure. The textToSpeech function in the example above drops into any TypeScript project as a single self-contained function.
For input longer than 1 KB or uncompressed WAV output, switch to the Long Content (Polling) API.