Create a Meditation App with AI-Generated Voice
Why a Voice‑First Meditation App? Meditation is all about getting the mind into a calm, focused state. A soothing voice can guide users deeper than any static text. With modern text‑to��speech (TTS) APIs you can generate lifelike narration on the fly, personalize the tone for each session,

Meditation is all about getting the mind into a calm, focused state. A soothing voice can guide users deeper than any static text. With modern text‑to��speech (TTS) APIs you can generate lifelike narration on the fly, personalize the tone for each session, and even clone a favorite teacher’s voice. The result? A lightweight app that feels like a personal meditation coach, without the overhead of recording hours of audio.
In this post we’ll walk through building a simple meditation‑assistant that:
We’ll use ElevenLabs as the TTS engine because its API delivers expressive, human‑like speech and supports voice cloning out of the box. The affiliate link is https://try.elevenlabs.io/kr07zfuqn1bp – feel free to sign up and get some free credits.
First, create an account at the link above. Once you’re logged in, grab your API key from the dashboard – you’ll need it for every request.
For a quick prototype we��ll stick with a pre‑built “calm” voice, but later you can replace it with a cloned voice of your own meditation teacher.
Below is a minimal Python wrapper that posts a script and streams back an MP3 file. We’ll use requests for simplicity.
import os import requests API_KEY = os. getenv ( " ELEVENLABS_API_KEY " ) # keep it out of source control VOICE_ID = " EXAVITQu4vr4xnSDxMaL " # example voice – pick a calm one from the dashboard BASE_URL = " https://api.elevenlabs.io/v1 " def synthesize ( text: str, output_path: str = " output.mp3 " ): url = f " { BASE_URL } /text-to-speech/ { VOICE_ID } " headers = { " xi-api-key ": API_KEY, " Content-Type ": " application/json ", " Accept ": " audio/mpeg " } payload = { " text ": text, " model_id ": " eleven_monolingual_v1 ", " voice_settings ": { " stability ": 0.75, " similarity_boost ": 0.85 } } response = requests. post ( url, json = payload, headers = headers, stream = True ) response. raise_for_status () with open ( output_path, " wb " ) as f: for chunk in response. iter_content ( chunk_size = 8192 ): f. write ( chunk ) print ( f " ✅ Audio saved to { output_path } " ) if __name__ == " __main__ ": script = """ Close your eyes. Take a slow, deep breath in... hold for three counts... exhale gently, feeling tension melt away. Continue this rhythm for the next two minutes.
""" synthesize ( script. strip ()) Enter fullscreen mode Exit fullscreen mode What’s happening?
Run the script, and you’ll have a output.mp3 you can play in any media player.
If you prefer not to write code yet, a single curl call does the job:
curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/EXAVITQu4vr4xnSDxMaL" \ -H "xi-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: audio/mpeg" \ -d '{ "text": "Take a deep breath in, hold, and release slowly.", "model_id": "eleven_monolingual_v1", "voice_settings": { "stability": 0.7, "similarity_boost": 0.9 } }' \ --output meditation.mp3 Enter fullscreen mode Exit fullscreen mode Replace YOUR_API_KEY with the key from your ElevenLabs dashboard. The response is an MP3 file ready for playback.
Hard‑coding every meditation line gets tedious fast. Instead, let the app generate a fresh script each session using a language model (e.g., OpenAI’s GPT‑4). Here’s a tiny Flask endpoint that stitches everything together:
from flask import Flask, request, send_file import openai import tempfile app = Flask ( __name__ ) openai. api_key = os. getenv ( " OPENAI_API_KEY " ) def generate_script ( duration_seconds: int ) -> str: prompt = f """ Write a guided meditation script for a { duration_seconds // 60 } -minute session. Include breathing cues, gentle reminders, and a closing gratitude statement. Keep each cue under 15 words.
""" resp = openai. ChatCompletion. create ( model = " gpt-4o-mini ", messages = [{ " role ": " user ", " content ": prompt }] ) return resp. choices [ 0 ]. message. content. strip () @app.route ( " /meditate " ) def meditate (): minutes = int ( request. args. get ( " minutes ", 5 )) script = generate_script ( minutes * 60 ) # Use the synthesize function from the previous section with tempfile. NamedTemporaryFile ( suffix = ".mp3 ", delete = False ) as tmp: synthesize ( script, output_path = tmp. name ) return send_file ( tmp. name, mimetype = " audio/mpeg ", as_attachment = False ) if __name__ == " __main__ ": app. run ( debug = True ) Enter fullscreen mode Exit fullscreen mode Now a GET request like GET /meditate?minutes=7 returns a fresh 7‑minute meditation audio stream.
You can host this on any cloud provider (Render, Fly.io, Vercel serverless functions) and point your mobile front‑end at the endpoint.
Below is a minimal React component that fetches the audio and plays it using the HTML5 <audio> element.
import { useState } from " react "; export default function MeditationPlayer () { const [ loading, setLoading ] = useState ( false ); const [ src, setSrc ] = useState ( null ); const startSession = async ( minutes = 5 ) => { setLoading ( true ); const res = await fetch ( `/meditate?minutes= ${ minutes } ` ); const blob = await res. blob (); const url = URL. createObjectURL ( blob ); setSrc ( url ); setLoading ( false ); }; return ( < div style = { { textAlign: " center ", marginTop: " 2rem " } } > < button onClick = { () => startSession ( 5 ) } disabled = { loading } > { loading? " Preparing… ": " Start 5‑minute Session " } </ button > { src && ( < audio controls autoPlay src = { src } style = { { marginTop: " 1rem ", width: " 100% " } } /> ) } </ div > ); } Enter fullscreen mode Exit fullscreen mode Because the server streams an MP3, the browser can start playback as soon as enough data arrives, giving a near‑instant experience.
If you ever want to clone a specific teacher’s voice, ElevenLabs’ cloning endpoint requires just a few minutes of clean audio. After the clone is ready you simply swap the VOICE_ID in the code above.
Building a meditation app with AI‑generated voice is now a weekend project rather than a multi‑month undertaking. By leveraging ElevenLabs’ expressive TTS, you get:
All that’s left is to iterate on the scripts, polish the UI, and maybe add a subscription model for premium voice packs.
Head over to https://try.elevenlabs.io/kr07zfuqn1bp, grab your free credits, and start experimenting with lifelike meditation narration today. Happy coding—and happy breathing!