Lazyread local-first listening library runtime
Project description
Lazyread
Turn a URL or Markdown file into a private listening article with natural local speech, synchronized word highlighting, auto-scroll, and saved highlights.
https://github.com/user-attachments/assets/df6f44ee-572a-4a08-a0d8-7d8acc78fb6b
Install
Lazyread currently supports Apple Silicon Macs running macOS 14 or newer. It also needs Node.js 20.19+, FFmpeg 6+, and UV.
Install the Lazyread skill globally:
npx --yes skills add https://github.com/jayfarei/lazyread/ --global --agent universal --yes
Restart your agent, then invoke the skill with a URL or Markdown file:
$lazyread https://example.com/article
On first use, Lazyread explains the local setup and asks before downloading about 5.4 GB of speech and alignment models. The skill then creates the article, waits for narration, verifies the reader, and returns a reusable local URL.
Update
If you installed the skills with the command above, update both the skills and the Lazyread runtime with:
npx --yes skills update lazyread defuddle --global --yes
uvx --refresh lazyread doctor
npx skills remembers the source of each installed skill and updates its
managed copy and agent links in place. If Lazyread was installed as a persistent
UV tool, run uv tool upgrade --reinstall lazyread instead of the uvx command.
If the skills were installed by Lazyread itself, refresh those copies with
lazyread install-skills --force instead of npx skills update.
Models, cache, and wait times
Lazyread installs two pinned MLX models into one shared cache for every article:
- Speech:
mlx-community/Qwen3-TTS-12Hz-1.7B-CustomVoice-bf16 - Word alignment:
mlx-community/Qwen3-ForcedAligner-0.6B-8bit
The models use about 5.4 GB; allow at least 8 GB of working disk space during setup. They download only on first-time setup or after the model cache is removed. Model revisions are pinned per Lazyread release so the same input remains reproducible.
Narration is generated once and reused. Lazyread keeps temporary speech chunks so an interrupted job or alignment repair can resume without repeating valid speech generation. The finished FLAC audio and word timings are stored with the article. Each browser also downloads the complete finished track into its own Cache Storage before enabling Play; later listening is immediate and works offline in that browser.
The readable article appears within seconds, while narration continues in the background. Generation time depends on article length, Mac hardware, and cache hits. On the tested M4 Pro:
| Article length | Generation time | Audio produced | Finished audio size |
|---|---|---|---|
| 1,145 words | 1:11 | 9:38 | 13 MB |
| 10,068 words | 70:16 | 108:04 | 125 MB |
Each browser or device performs its own one-time preload of the finished audio.
Run uvx lazyread storage to see the space used by articles, temporary chunks,
and models.
What you get
- Natural speech generated locally on your Mac
- Word-by-word tracking and automatic scrolling
- Keyboard navigation, playback speed, and sentence highlights
- A durable private library at
http://127.0.0.1:4242/library - Optional private access through your Tailscale network
Article content, audio, highlights, and models remain on your Mac. Creating an article from a URL still accesses the original website for extraction.
The runtime is also published on PyPI.
For development and release details, see design/ and
RELEASING.md.
License
MIT. See THIRD_PARTY_NOTICES.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lazyread-0.2.0.tar.gz.
File metadata
- Download URL: lazyread-0.2.0.tar.gz
- Upload date:
- Size: 102.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0347d24d20673e44caac9b4f46555c9aedd1dd2c6dfb073c62b074389d66d3d
|
|
| MD5 |
354d99dc7f793a4daa44af2b06352399
|
|
| BLAKE2b-256 |
a09f8e6c97959e17697577d17c2cfaab8e18981c920032c7ab1a03d46d10e95b
|
File details
Details for the file lazyread-0.2.0-py3-none-any.whl.
File metadata
- Download URL: lazyread-0.2.0-py3-none-any.whl
- Upload date:
- Size: 98.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f35aa4f15b7e77d7b3da1bcbb51ee0d4e0fb23aa131b96e6961096ea4ab8801d
|
|
| MD5 |
ef256156beabed0a160f19f852d3b3cb
|
|
| BLAKE2b-256 |
2f603ee74736ac69c594ec821503c81249d798bd1526100ef379a03ea5a419d2
|