pyttsx3: offline text to speech in Python, tested against your OS
Offline Text To Speech synthesis for python
At a glance
- What is it?
- pyttsx3 wraps the speech engine your operating system already ships, so it speaks without a network call. The trade-off is that voice quality and availability are whatever SAPI5, NSSpeechSynthesizer, AVSpeech or eSpeak give you.
- Who is it for?
- Adopt pyttsx3 when you need speech that works without a network call and you accept whatever voices the host OS provides: kiosk readouts, accessibility helpers, batch generation of WAV or MP3 files on a machine you control. Do not adopt it when you need consistent voice quality across machines, cloud-grade neural voices, or a headless Linux container without eSpeak installed.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 59 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 18, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What pyttsx3 is for, and who ends up using it
pyttsx3 is a Python 3 text-to-speech library whose distinguishing property, in the README's words, is that "it works offline". That single sentence defines both its audience and its limits. It is not a speech model. It is an adapter layer that finds the speech engine already present on the machine and drives it through a common API.
The people who reach for it are usually in one of three situations. First, a script or desktop tool needs to read something aloud on a machine that may have no internet connection at all, such as a kiosk, a lab instrument, or an air-gapped workstation. Second, a developer wants to generate audio files in bulk from text without paying per character or shipping text to a third party. Third, someone is building an accessibility feature into a Python application and wants the smallest possible dependency that still produces sound.
If your requirement is a specific voice, a specific accent, or a specific audio quality, this library is the wrong starting point. It gives you the voices the host system has, not a catalogue you choose from.
The engine table: one API, four very different backends
The README publishes a support matrix that is the most important thing on the page. On Windows, pyttsx3 drives SAPI5. On macOS it can drive AVSpeech, eSpeak or the deprecated NSSpeechSynthesizer. On Linux it drives eSpeak. There is no engine of its own anywhere in that list.
That design is why the library is small and why it installs without downloading voice data, but it also means the behaviour you get is the behaviour of the underlying engine. Two developers running the same pyttsx3 code on Windows and on Linux will hear different voices, different prosody, and possibly different handling of punctuation. The API is portable; the output is not.
The README flags two caveats directly: AVSpeechSynthesizer support is described as experimental, and NSSpeechSynthesizer is noted as deprecated by Apple. Those notes matter for anyone targeting current macOS, because the macOS path is the one with the least settled backend.
The pyproject.toml shows how the platform split is wired at install time. Windows pulls in comtypes and pywin32; Darwin pulls in pyobjc-framework-cocoa, pyobjc-framework-AVFoundation and pyobjc-framework-ExceptionHandling. Linux pulls in nothing extra, which is exactly why the README sends Linux users to the system package manager instead.
Installing pyttsx3 and getting the first sentence spoken
The documented install is a single pip command. The README adds one troubleshooting note: if installation errors appear, upgrade wheel first.
pip install pyttsx3On Linux, the Python package alone is not enough. The README states that if voice output is not working on a Linux system, install espeak-ng and libespeak1 from the distribution repositories.
sudo apt update && sudo apt install espeak-ng libespeak1With that in place, the smallest working program creates an engine, queues one utterance, and blocks until speech finishes. runAndWait() is what actually produces sound; say() only queues.
import pyttsx3
engine = pyttsx3.init()
engine.say("I will speak this text")
engine.runAndWait()The README also documents a one-line form for the default configuration, which skips the engine object entirely.
import pyttsx3
pyttsx3.speak("I will speak this text")For macOS, the README warns that init() can raise a pyobjc-related error and prescribes installing pyobjc version 9.0.1 or later. That is a real first-run obstacle, not a footnote.
Rate, volume, voice selection and writing audio to a file
The three tunable properties are rate, volume and voice. Rate and volume are read and written through getProperty and setProperty; volume is documented as a range from 0 to 1. Voices come back as a list, and you select one by assigning its id.
import pyttsx3
engine = pyttsx3.init()
rate = engine.getProperty('rate')
engine.setProperty('rate', 125)
volume = engine.getProperty('volume')
engine.setProperty('volume', 1.0)
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)
engine.say("Hello World!")
engine.runAndWait()
engine.stop()Note the indexing in the README's own comment: index 0 is described as male and index 1 as female. Treat that as illustrative rather than guaranteed. The list is whatever the host engine reports, so the ordering is a property of the machine, not of pyttsx3. Code that hardcodes voices[1] for a female voice will behave unpredictably on a system whose voice list is ordered differently.
File output uses save_to_file, which is also asynchronous and therefore needs runAndWait() after it. The README notes that on Linux this path requires espeak-ng to be installed.
engine.save_to_file('Hello World', 'test.mp3')
engine.runAndWait()The repository ships an example directory containing main.py, repeatvoice.py and a voicefile.mp3, so there is a runnable reference beyond the README snippets.
Where pyttsx3 breaks down
The clearest failure mode is the one the README itself anticipates: on Linux, a correct pip install can still produce no audio. The Python layer is installed and importable, but the speech engine it delegates to is missing. Nothing in the library detects this for you in a way the README describes; the fix is a system package install that your deployment tooling has to know about.
The second limitation is voice portability. Because voices come from the OS, a container image, a fresh CI runner and a developer laptop will expose different lists. Any code that selects a voice by index is fragile. Selecting by matching against the voice's id or name is the safer pattern, though the README does not document a stable naming scheme to match on.
The third is quality. eSpeak is a formant synthesizer, and its output is recognisable as such. If your product's value depends on natural-sounding speech, an OS-provided engine is not the tool, and pyttsx3 cannot fix that because it does not synthesize anything itself.
The fourth is the macOS backend situation. With AVSpeech described as experimental and NSSpeechSynthesizer deprecated by Apple, the macOS path carries more uncertainty than Windows or Linux. The README does not document rollback or fallback behaviour between those engines.
Finally, the README does not document thread safety, queue semantics beyond say() and runAndWait(), or what happens when save_to_file targets a format the underlying engine cannot write. Those are gaps, not necessarily defects, but they are gaps a production integration will run into.
pyttsx3 versus gTTS and cloud speech APIs
The natural alternative is gTTS, which is named as a keyword in this project's own pyproject.toml. The difference in approach is fundamental rather than cosmetic. gTTS sends your text to Google's translation service and streams back an MP3, so it depends on a network connection and on a third-party service accepting the request. pyttsx3 never leaves the machine.
That single difference decides most adoption questions. An air-gapped deployment, a privacy-sensitive transcript, or a script that must run on a machine with no outbound access rules out gTTS immediately. Conversely, if you want a consistent, natural-sounding voice across every platform you deploy to, the OS-engine approach of pyttsx3 works against you, because there is no single voice to standardise on.
Cloud neural TTS services sit at the other end of the same axis: better voices, per-character cost, network dependency, and text leaving your machine. pyttsx3 occupies the opposite corner. It is worth being explicit that these are not interchangeable quality tiers; they are different constraints being optimised.
The README also invites the opposite direction of extension: "Feel free to wrap another text-to-speech engine for use with pyttsx3." The pyproject.toml packages both pyttsx3 and pyttsx3.drivers, which is consistent with a driver-based design where backends are pluggable.
Licence, maintenance and upgrade cost
pyttsx3 is released under MPL-2.0, declared both in the repository's LICENSE file and in the pyproject.toml license field. The Mozilla Public License is file-level copyleft: modifications to MPL-covered files must be made available under the same licence, while larger works that combine the library with other code can generally be distributed under other terms. That is a summary of the licence's structure, not legal advice, and anyone embedding the library in a shipped product should read the licence text or take their own counsel.
The practical licence question for most teams is whether they intend to modify pyttsx3's driver code. If they only import it, the obligation is largely about preserving notices. If they patch a driver and redistribute, the patched files carry the MPL terms.
On maintenance: the repository is not archived, and the last push was on 2026-07-22. The most recent tagged release is v2.99, dated 2025-07-07, following v2.98 in September 2024 and v2.95 earlier that same month. So there is release activity within roughly the last year and repository activity more recent than that. The pyproject.toml declares support for Python 3.10 through 3.14, which is a fairly current range.
Upgrade cost is low by construction. The public surface is a handful of functions: init, say, runAndWait, stop, getProperty, setProperty, save_to_file, plus the module-level speak. The main upgrade risk is not API churn but platform drift, particularly the macOS backends where Apple's deprecation of NSSpeechSynthesizer and the experimental status of AVSpeech may force changes that have nothing to do with pyttsx3's own release cadence.
Editorial conclusion
Adopt pyttsx3 when you need speech that works without a network call and you accept whatever voices the host OS provides: kiosk readouts, accessibility helpers, batch generation of WAV or MP3 files on a machine you control. Do not adopt it when you need consistent voice quality across machines, cloud-grade neural voices, or a headless Linux container without eSpeak installed. Before committing, verify three things on your target platform: that pyttsx3.init() returns an engine without raising, that engine.getProperty('voices') lists the voices you intend to use, and that engine.save_to_file() writes a file you can actually play back.
Frequently asked questions
Is pyttsx3 free to use?
Yes. The repository declares MPL-2.0 in both the LICENSE file and pyproject.toml. That licence permits use in larger works, with file-level copyleft obligations if you modify and redistribute MPL-covered files.
How do I install pyttsx3 in Python?
Run pip install pyttsx3. The README adds that if installation errors appear, you should first upgrade wheel with pip install --upgrade wheel. On Linux you also need espeak-ng and libespeak1 installed from the system package manager.
What is pyttsx3?
It is a text-to-speech conversion library for Python 3 that works offline. Rather than synthesizing speech itself, it drives the speech engine already present on the operating system: SAPI5 on Windows, eSpeak on Linux, and AVSpeech, eSpeak or NSSpeechSynthesizer on macOS.
How do I use pyttsx3 in Python?
Call pyttsx3.init() to create an engine, pass text to engine.say(), then call engine.runAndWait() to actually produce the speech. The README also shows a one-line pyttsx3.speak("text") form for the default configuration.
How do I install pyttsx3 on Ubuntu?
Install the Python package with pip install pyttsx3, then install the engine it delegates to: sudo apt update && sudo apt install espeak-ng libespeak1. The README gives that second step for Linux systems where voice output is not working.
How do I install pyttsx3 on a Mac?
Install with pip install pyttsx3. The README notes that if init() raises an error related to pyobjc, you should install pyobjc version 9.0.1 or later with pip install pyobjc>=9.0.1.
Community notes