DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

Build and Host a Text-to-Speech SaaS with Node.js and Bluehost

Why a Text‑to‑Speech SaaS?

Voice AI is no longer a niche hobby—businesses are adding audio to blogs, e‑learning platforms, and customer‑support bots every day. Building a Text‑to‑Speech (TTS) SaaS gives you a product you can monetize via subscription, per‑minute usage, or even a free tier with limits.

In this guide you’ll see how to:

  1. Wire up the ElevenLabs API for high‑quality neural speech and voice cloning.
  2. Wrap the API in a simple Node.js/Express service that accepts plain text and returns an MP3 file.
  3. Deploy the whole thing on Bluehost, the affordable hosting platform that makes Node.js apps feel like static sites.

Let’s dive in—no deep‑learning background required, just a bit of JavaScript and a willingness to experiment.


1. Set Up Your Project

# Create a fresh folder
mkdir tts-saas && cd tts-saas

# Initialise npm and install dependencies
npm init -y
npm install express dotenv node-fetch@2
Enter fullscreen mode Exit fullscreen mode
  • express – our HTTP server.
  • dotenv – keep API keys out of source control.
  • node-fetch – simple wrapper for making HTTP calls to ElevenLabs.

Create a .env file (add this to .gitignore later) and paste your ElevenLabs API key:

ELEVENLABS_API_KEY=YOUR_ELEVENLABS_API_KEY
Enter fullscreen mode Exit fullscreen mode

You can obtain a key by signing up at ElevenLabs. Their free tier already gives you several thousand characters per month, which is perfect for prototyping.


2. The Core TTS Route

Create index.js and add the following code:

require('dotenv').config();
const express = require('express');
const fetch = require('node-fetch');
const app = express();

app.use(express.json());

const ELEVENLABS_API = 'https://api.elevenlabs.io/v1/text-to-speech';
const VOICE_ID = 'EXAVITQu4vr4xnSDxMaL'; // default “Rachel” voice – replace with your cloned voice ID

app.post('/synthesize', async (req, res) => {
  const { text, voiceId } = req.body;
  if (!text) return res.status(400).json({ error: 'Missing `text` field' });

  try {
    const response = await fetch(`${ELEVENLABS_API}/${voiceId || VOICE_ID}`, {
      method: 'POST',
      headers: {
        'xi-api-key': process.env.ELEVENLABS_API_KEY,
        'Content-Type': 'application/json',
        Accept: 'audio/mpeg',
      },
      body: JSON.stringify({
        text,
        model_id: 'eleven_monolingual_v1',
        voice_settings: { stability: 0.75, similarity_boost: 0.85 },
      }),
    });

    if (!response.ok) {
      const err = await response.json();
      return res.status(response.status).json(err);
    }

    // Stream the MP3 straight back to the client
    res.set('Content-Type', 'audio/mpeg');
    response.body.pipe(res);
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`🚀 TTS service listening on ${PORT}`));
Enter fullscreen mode Exit fullscreen mode

How It Works

  • The route expects a JSON body with a text field (and optionally a voiceId if you’ve cloned a custom voice).
  • We forward the request to ElevenLabs, ask for an MP3 (Accept: audio/mpeg), and pipe the response directly to the client.
  • Errors from the ElevenLabs API surface as proper HTTP status codes, making debugging easy.

Tip: If you’ve created a custom voice clone on ElevenLabs, replace VOICE_ID with the clone’s ID or pass it in the request body. Voice cloning works the same way—just a different identifier.


3. Testing Locally with cURL

Run the server:

node index.js
Enter fullscreen mode Exit fullscreen mode

Then fire a quick request:

curl -X POST http://localhost:3000/synthesize \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello, developer! This is your new TTS API."}' \
  --output hello.mp3
Enter fullscreen mode Exit fullscreen mode

You should now have a hello.mp3 file that plays the spoken sentence. If it works locally, you’re ready for the cloud.


4. Deploying to Bluehost

Why Bluehost?

Bluehost offers a simple, affordable way to host Node.js applications without wrestling with complex Docker setups or expensive VPS plans. Their shared hosting environment includes a built‑in Node.js manager, one‑click SSL, and a friendly UI that lets you point a domain to your app in minutes.

Step‑by‑Step Deployment

  1. Create a Bluehost account – sign up via the affiliate link Bluehost. You’ll get a free domain for the first year and a $2.95/mo starter plan that supports Node.js.

  2. Upload your code

    • Zip the entire project folder (excluding node_modules).
    • In the Bluehost cPanel, go to File Manager → Upload and place the zip in public_html.
    • Extract the archive.
  3. Install dependencies

    • Open Terminal from cPanel (or SSH in).
    • Navigate to the project folder: cd public_html/tts-saas
    • Run npm install – this will recreate node_modules on the server.
  4. Configure environment variables

    • In cPanel, click Setup Node.js App → Create Application.
    • Choose the runtime (e.g., Node 18), set the app’s Document Root to the folder you just uploaded, and add the ELEVENLABS_API_KEY variable under Environment Variables.
  5. Start the app

    • In the same Node.js manager, click Run npm start (or specify node index.js).
    • Bluehost will assign a temporary URL like https://yourdomain.com/tts-saas. Test it with the same cURL command, just replace the host.
  6. Optional: Set a custom subdomain

    • Add a DNS A record for api.yourdomain.com pointing to your Bluehost server IP.
    • Update the Node.js manager’s Domain field to use the subdomain, then restart the app.

That’s it! Your TTS SaaS is live, secure, and reachable from anywhere.


5. Adding a Simple Rate‑Limiter (Production‑Ready)

When you open your API to the public, you’ll want to prevent abuse. Here’s a lightweight middleware using the express-rate-limit package:

npm install express-rate-limit
Enter fullscreen mode Exit fullscreen mode

Add it to index.js before the route definitions:

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 30, // max 30 requests per minute per IP
  message: { error: 'Too many requests, please try again later.' },
});

app.use(limiter);
Enter fullscreen mode Exit fullscreen mode

Now each IP can only hit the /synthesize endpoint 30 times per minute—enough for most demos while keeping costs under control.


6. Monetizing the Service

With the core API in place, you can layer on:

  • API keys per customer stored in a tiny SQLite or MongoDB collection.
  • Usage tracking (characters processed) to enforce free‑tier limits.
  • Web dashboard built with React or Vue that lets users type text, pick a voice, and download the MP3—all calling the same /synthesize endpoint behind the scenes.

All of these features can live on the same Bluehost account; you only need to add a few more files and a modest database.


7. Next Steps & Resources

  • Voice Cloning – Explore ElevenLabs’ voice‑cloning endpoint to let users upload a short sample and generate a personal voice. The API call is identical; you just swap the voiceId with the newly created clone’s ID.
  • SSML Support – ElevenLabs also accepts SSML (Speech Synthesis Markup Language) for richer prosody. Pass an ssml field instead of plain text if you need pauses, emphasis, or phoneme control.
  • Caching – Store generated MP3s in a CDN (Cloudflare, BunnyCDN) to reduce repeated calls for the same text.

8. Wrap‑Up

You now have a fully functional Text‑to‑Speech SaaS built with Node.js, powered by ElevenLabs’ state‑of‑the‑art neural voices, and hosted on the Bluehost platform that makes deployment feel as easy as publishing a static site.

Give it a spin, experiment with custom voice clones, and start charging for the minutes you generate. The barrier to entry is low, but the impact—adding a human‑like voice to any product—can be huge.

Ready to build?

  • Grab your ElevenLabs API key at ElevenLabs and start generating natural‑sounding speech today.
  • Deploy your code in minutes with the affordable, developer‑friendly hosting from Bluehost.

Happy coding, and may your SaaS be as smooth as the voices it produces!

Top comments (0)