Skip to content

Sami

Home

Projects

About

Blog

Home

Projects

About

Blog

← Back to Projects

Speeedy

Local-first RSVP speed-reading PWA with a custom engine, ambient focus audio, accessibility modes, and full reading analytics. No account required.

Personal Project
Lit
TypeScript
PWA
IndexedDB
View Live Site →View on GitHub

The Problem

Existing RSVP tools were fragmented: some focused on speed, others on privacy, but none offered a complete environment — accessibility modes for dyslexia and visual stress, long-form library management, measurable skill progression, and a polished reading experience — all without requiring an account or sending data to a server. Eye-tracking fatigue from saccades wastes a measurable portion of reading time, and no existing free tool addressed it holistically.

Architecture

  • →

    Custom RSVP engine (rsvp-engine.ts): token-based playback with play/pause/seek, per-word progress events, estimated remaining time, and live timing rescheduling when speed changes mid-session. ORP computation splits every word into before/pivot/after segments so the focal letter always lands on the same screen position.

  • →

    Smart Speed adaptive timing: base WPM is adjusted per-word based on character count, internal punctuation (dashes, commas, quotes), sentence and paragraph boundaries, and configurable pause multipliers — preserving natural reading cadence at 500+ WPM.

  • →

    Local-first persistence: IndexedDB (via idb) with schema versioning, a profile store, and a document library capped at 20 items with SHA-256 deduplication. Reading progress, session history, streaks, and all settings sync automatically without any backend.

  • →

    Document parsing pipeline (text-parser.ts): PDF via pdfjs-dist with X/Y position-based line reconstruction, DOCX via mammoth, EPUB OPF spine parsing via JSZip, plus RTF, HTML, CSV, ODT, TXT, and Markdown. Twelve formats handled in the browser without any upload.

  • →

    Web Audio API ambient system (audio-service.ts): procedurally generated white, pink, and brown noise with crossfade loop-boundary smoothing; per-word click sounds with configurable pitch; visibility/focus-based audio context recovery. All generated in-browser, no audio files required.

  • →

    Accessibility modes: OpenDyslexic font + increased spacing for dyslexia mode, Irlen-style tinted overlays with color picker, bionic reading bolding, ORP guide markers, peripheral ghost-word context, configurable pivot offset, and RTL/Arabic layout compensation via measured pixel offsets.

  • →

    Stats and benchmark system: session recording with crypto.randomUUID IDs, streak calculation, WPM trend and 14-day bar charts rendered in pure SVG/CSS, and a timed benchmark test with a 10-question comprehension quiz that calibrates the reader's starting speed.

  • →

    Social sharing without a backend: share payloads are base64-encoded into URL hashes. Profile stat cards are rendered to PNG via html-to-image for download. Public share links decode entirely in the browser on the share route.

  • →

    PWA and CI: Workbox static caching via vite-plugin-pwa, Vite chunk splitting for PDF/DOCX/JSZip/html-to-image/Lit, Cloudflare Pages hosting. 139 unit tests (Vitest) and 6 Playwright E2E suites covering the full reading flow, benchmark, keyboard shortcuts, and settings persistence.

Technical Challenges

  • →

    Reconstructing readable prose from PDFs using raw X/Y glyph positions and font metrics — PDFs have no concept of 'lines' or 'paragraphs'

  • →

    Crossfade-smooth ambient noise loops using the Web Audio API with no audio files, so loop boundaries are imperceptible at any volume

  • →

    RTL word display: Arabic pivot letters require measured DOM offsets to land in the correct visual position rather than the CSS text-alignment position

  • →

    Schema-versioned IndexedDB with blocked/blocking multi-tab upgrade handling so data never corrupts when the user has the app open in multiple tabs

  • →

    Keeping chunk sizes manageable (PDF, DOCX, EPUB parsers are heavy) while keeping initial load instant via Vite manual chunk splitting and lazy loading

Results

  • ✓

    Released as v1.0.0 on 2026-03-27. Deployed on Cloudflare Pages at speeedy.pages.dev

  • ✓

    Custom RSVP engine supports 500+ WPM with ORP centering and adaptive Smart Speed pacing across 12 document formats

  • ✓

    Full local-first profile system: library, streaks, WPM history, benchmark baseline, and settings — zero server round-trips

  • ✓

    139 unit tests passing across the RSVP engine, stats service, text parser, and text utilities; 6 Playwright E2E suites covering the end-to-end reading flow

  • ✓

    Procedural Web Audio ambient system and full dyslexia/Irlen accessibility stack with no external dependencies for either

Speeedy - Speeedy – RSVP Reader Dashboard