Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lazyread-0.1.0.tar.gz (100.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lazyread-0.1.0-py3-none-any.whl (95.6 kB view details)

Uploaded Python 3

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

Hashes for lazyread-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b6e655c3e1914029c6f0bc1c5c1506518f9b0eadacde23d96e2dc5bef11772b8
MD5 64d5e2801d3ff31b89b122a62c81d8c9
BLAKE2b-256 bbda439c8aba6ba1532a24c603b13f4f48a543a69b325fd7bdcbfc9555992a92

See more details on using hashes here.

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

Hashes for lazyread-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8b251f4b92b1e910a8786803ea091b69e03edbbafdff43902a1fe8d22b6509e2
MD5 56363329f934c65305cd025181fe3f93
BLAKE2b-256 c98a5ab4d286c9096aa82eb251e7af8f65c0a56d64fe70956ac604b28f458361

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page