Lazyread local-first listening library runtime
Project description
Lazyread
Lazyread turns URLs and Markdown into a private local listening library: readable article typography, natural on-device narration, exact word highlighting, complete-track preloading, progress, telemetry, and mobile controls in one durable app.
It is an early public release for Apple Silicon Macs. Text extraction and the web library are lightweight; natural narration uses MLX, Qwen3-TTS 1.7B CustomVoice, and Qwen3 ForcedAligner. Article content and finished audio stay on the Mac. URL extraction still accesses the source website.
Prerequisites are macOS 14 or newer, Node.js 20.19+, FFmpeg 6+, and UV 0.5+.
lazyread doctor reports exact versions and Homebrew repair commands before
setup changes anything. These small system tools are not installed silently;
Defuddle, Python/MLX packages, and models are installed into app-owned storage.
Quick start
The runtime is currently installed from GitHub through UVX:
uvx --from git+https://github.com/JayFarei/lazyread lazyread doctor
uvx --from git+https://github.com/JayFarei/lazyread lazyread setup
The product, command, Python module, repository, skill, and PyPI distribution
are all named lazyread. After the first release, the public entrypoint is simply
uvx lazyread.
setup first prints the compatibility and storage disclosure. The confirmed command installs pinned dependencies under ~/Library/Application Support/Lazyread and downloads about 5.4 GB of speech/alignment models:
uvx --from git+https://github.com/JayFarei/lazyread lazyread setup --yes
uvx --from git+https://github.com/JayFarei/lazyread lazyread install-skills
uvx --from git+https://github.com/JayFarei/lazyread lazyread serve --detach
Restart the agent host after installing skills, then invoke:
$lazyread https://example.com/article
The companion skill reviews Defuddle extraction before submitting the source. The browser also has a baseline URL/Markdown form at http://127.0.0.1:4242/library.
Private Tailscale access
Add a single tailnet-only listener without touching other Serve routes:
uvx --from git+https://github.com/JayFarei/lazyread lazyread expose --https-port 7447
Lazyread never enables Funnel and never resets the machine's Tailscale Serve configuration. The Tailscale listener trusts the tailnet: every principal allowed to reach the Mac by its tailnet ACL can use the complete library API, including deletion. Use it only on a personal tailnet or restrict the device/port with Tailscale ACLs. A future public multi-user release will add per-user pairing.
What is persisted
The library lives under ~/Library/Application Support/Lazyread unless LAZYREAD_HOME is set. SQLite holds catalog/job state; article folders hold source Markdown, display and speech projections, FLAC/WAV audio, timings, and telemetry. Delete moves an article to trash; purge is separate. Model and chunk storage are reported independently.
The server survives independently of the heavy narration worker. Jobs run serially, persisted progress is replayed over SSE, interrupted work is recoverable, and the MLX process exits when its queue item finishes so it does not retain unified memory while idle.
Current pinned speech stack
Verified 14 July 2026 against the official upstream repositories:
- MLX-Audio
64e8416c303fb3b3463dab8eb4ebd78c55a87c1a - Qwen3-TTS 1.7B CustomVoice
52f4770fd9726457eae3d3b6aa92047a25a10776 - Qwen3 ForcedAligner
0e1a68e91d815300c7c9754b2a7639378b23db15 - Defuddle
0.19.1
Revisions are immutable for reproducibility. A release update verifies and advances them; normal article creation does not silently upgrade the environment.
Development
uv sync --extra test
uv run --extra test pytest
uvx ruff check src tests
cd web
npm ci
npm test
npm run build
npm audit --omit=dev
Run the full app with deterministic silent narration for UI/integration work:
LAZYREAD_HOME=/tmp/lazyread-dev LAZYREAD_WORKER=fake \
PYTHONPATH=src uv run lazyread serve --port 4246
The architecture and measured 10,068-word scientific-paper production run are documented in design/.
Maintainer release steps are documented in RELEASING.md.
License
MIT. See THIRD_PARTY_NOTICES.md for bundled skill attribution.
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.1.0.tar.gz.
File metadata
- Download URL: lazyread-0.1.0.tar.gz
- Upload date:
- Size: 100.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","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 |
b6e655c3e1914029c6f0bc1c5c1506518f9b0eadacde23d96e2dc5bef11772b8
|
|
| MD5 |
64d5e2801d3ff31b89b122a62c81d8c9
|
|
| BLAKE2b-256 |
bbda439c8aba6ba1532a24c603b13f4f48a543a69b325fd7bdcbfc9555992a92
|
File details
Details for the file lazyread-0.1.0-py3-none-any.whl.
File metadata
- Download URL: lazyread-0.1.0-py3-none-any.whl
- Upload date:
- Size: 95.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","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 |
8b251f4b92b1e910a8786803ea091b69e03edbbafdff43902a1fe8d22b6509e2
|
|
| MD5 |
56363329f934c65305cd025181fe3f93
|
|
| BLAKE2b-256 |
c98a5ab4d286c9096aa82eb251e7af8f65c0a56d64fe70956ac604b28f458361
|