DEV Community

VoiceDeveloper
VoiceDeveloper

Posted on

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

Why Text‑to‑Speech is the Next Big Thing in SaaS

If you’ve been following the voice AI space, you know that text‑to‑speech (TTS) is no longer a niche research project—it’s a commercial commodity. From audiobooks and accessibility tools to interactive voice assistants, the demand for high‑quality, expressive synthetic voices is exploding. Building a TTS SaaS lets you tap into that market while creating a product that can scale on a cloud platform with minimal operational overhead.

In this post I’ll walk you through the nuts and bolts of turning a Node.js backend into a fully‑featured TTS service, show how to use ElevenLabs’ state‑of‑the‑art API, and explain why Bluehost is the easiest, most affordable way to host and deploy your project.


1. Setting the Stage

What You’ll Need

Item Why
Node.js (≥18) Modern JavaScript runtime with built‑in fetch support
Express Lightweight web framework
ElevenLabs account High‑quality neural voices and voice cloning
Bluehost account Affordable shared hosting that supports Node.js
Optional: Docker For local development and CI/CD

Tip: Use nvm to manage Node.js versions locally.

Tip: Sign up for ElevenLabs through the affiliate link below to unlock a free credit tier.


2. Wiring Up ElevenLabs

ElevenLabs offers a straightforward REST API. The core endpoint for generating speech is /v1/text-to-speech/{voice_id}. You’ll need an API key, which you can get from the dashboard after creating an account.

# Store the key securely
export ELEVENLABS_API_KEY="YOUR_KEY_HERE"
Enter fullscreen mode Exit fullscreen mode

2.1. Create a Simple Express Server

// server.js
import express from 'express';
import fetch from 'node-fetch';
import dotenv from 'dotenv';

dotenv.config();
const app = express();
app.use(express.json());

const ELEVENLABS_API = 'https://api.elevenlabs.io/v1';
const VOICE_ID = 'YOUR_VOICE_ID'; // Pick one from your dashboard

app.post('/speak', async (req, res) => {
  const { text } = req.body;
  if (!text) return res.status(400).send({ error: 'Text is required' });

  try {
    const response = await fetch(`${ELEVENLABS_API}/text-to-speech/${VOICE_ID}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'xi-api-key': process.env.ELEVENLABS_API_KEY,
      },
      body: JSON.stringify({
        text,
        voice_settings: {
          stability: 0.5,
          similarity_boost: 0.5,
        },
      }),
    });

    if (!response.ok) throw new Error('ElevenLabs API error');

    const audioBuffer = await response.arrayBuffer();
    res.set('Content-Type', 'audio/mpeg');
    res.send(Buffer.from(audioBuffer));
  } catch (err) {
    console.error(err);
    res.status(500).send({ error: 'Failed to generate audio' });
  }
});

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

Note: Replace YOUR_VOICE_ID with an ID from your ElevenLabs account. You can also experiment with the voice_settings parameters to tweak the timbre.

2.2. Test the Endpoint

curl -X POST http://localhost:3000/speak \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello, world! This is a test of ElevenLabs TTS."}' \
  --output hello.mp3
Enter fullscreen mode Exit fullscreen mode

You should now have an hello.mp3 file that plays a high‑fidelity synthetic voice. 🎧


3. Adding Voice Cloning (Optional)

ElevenLabs also lets you clone a custom voice by uploading a short audio clip. Here’s a minimal example to upload a clip and generate a new voice ID:

const uploadResponse = await fetch(`${ELEVENLABS_API}/voices`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'xi-api-key': process.env.ELEVENLABS_API_KEY,
  },
  body: JSON.stringify({
    voice_name: 'MyCustomVoice',
    sample_file: 'file://path/to/sample.wav',
    sample_text: 'This is a sample sentence for voice cloning.',
  }),
});
const { voice_id } = await uploadResponse.json();
console.log('New voice ID:', voice_id);
Enter fullscreen mode Exit fullscreen mode

Once the voice is ready, you can use the voice_id in the /speak endpoint just like any other voice. This opens the door to a full‑featured SaaS where users can upload their own voice samples and generate personalized audio.


4. Packaging for Production

4.1. Use a Procfile

Bluehost’s shared hosting supports Node.js via a Procfile. Create the following file in your repo root:

web: node server.js
Enter fullscreen mode Exit fullscreen mode

4.2. Environment Variables

Bluehost allows you to set environment variables via the control panel. Add:

Variable Value
ELEVENLABS_API_KEY Your API key
PORT 80 (or let Bluehost set it)

4.3. Deploying

  1. Create a repo on GitHub or Bitbucket.
  2. Add a package.json with start script:
{
  "name": "tts-saas",
  "version": "1.0.0",
  "main": "server.js",
  "type": "module",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "dotenv": "^16.0.3",
    "express": "^4.18.2",
    "node-fetch": "^3.3.2"
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Push to your repo and connect it in Bluehost’s control panel.
  2. Launch – Bluehost will handle the build, install dependencies, and start the Node.js process.

Why Bluehost?

Bluehost offers a free domain and SSL, a simple control panel, and Node.js support—all for a fraction of the cost of VPS providers. It’s the perfect “starter” environment for a TTS SaaS, letting you focus on code instead of server management.


5. Scaling and Optimization

Concern Solution
Large audio files Stream the response instead of buffering the whole file.
Concurrent requests Use a worker pool or queue (BullMQ, Bee-Queue).
Cost control Monitor ElevenLabs usage and set per‑user quotas.
Latency Deploy to a region close to your user base. Bluehost offers multiple data centers.

6. Security & Best Practices

  • Rate limiting – Protect your API key by limiting how many requests a single IP can make per minute.
  • Input sanitization – Reject overly long texts or disallowed characters.
  • HTTPS – Bluehost provides free SSL; always serve over HTTPS to keep data encrypted.

7. Wrap‑Up

You now have a fully functional TTS SaaS built in Node.js, powered by ElevenLabs’ neural voices, and ready to host on Bluehost. The stack is lean, the deployment is hassle‑free, and the cost is minimal—perfect for a prototype or a small‑scale launch.

Give it a spin, iterate on the voice settings, and scale as your user base grows. And if you haven’t already, sign up for ElevenLabs through this link to get started with a generous free tier: https://try.elevenlabs.io/kr07zfuqn1bp.

When you’re ready to deploy, choose the easy, affordable path with Bluehost: https://bluehost.sjv.io/5k0d52.

Happy coding, and may your voices sound amazing!

Top comments (0)