openreader/docs-site/docs/reference/stack.md
Richard R b2bbd8fbef feat(data-storage): migrate all user state from IndexedDB to server-backed storage
Remove all Dexie/IndexedDB code and dependencies, including document and preview caches, local config, onboarding, and migration logic. Replace with server-backed React Query hooks for documents, folders, preferences, onboarding, and progress. Add browser Cache Storage for blob caching of documents, previews, and audio. Update API routes, database schema, and tests to support folder management, onboarding state, and server-side persistence of all user data. Refactor UI and hooks to use server state exclusively, ensuring all user state is synced and portable across devices.

BREAKING CHANGE: All user data, preferences, onboarding, and document state are now stored and synced on the server; browser IndexedDB is no longer used. Existing local-only data will not be available after this update.
2026-06-14 18:13:39 -06:00

4 KiB

title
Stack

Framework

Containerization and runtime

  • Docker (linux/amd64 and linux/arm64)
  • Shared entrypoint that runs DB migrations by default and can bootstrap embedded SeaweedFS before app startup

Next.js client

Next.js server

  • APIs: Route Handlers for sync, blob/content access, migrations, audiobook export, TTS/Whisper proxying
  • State sync: request-based today (not realtime push updates)
  • Authentication: Better Auth server handlers/adapters with anonymous session support
  • Metadata DB: Drizzle ORM with SQLite (better-sqlite3) by default and optional Postgres (pg)
    • App tables are manually maintained in Drizzle schema files
    • Auth tables are auto-generated by the Better Auth CLI and migrated alongside app tables via Drizzle
  • Blob storage: embedded SeaweedFS (weed mini) by default, or external S3-compatible storage via AWS SDK v3
  • TTS providers: OpenAI-compatible API (openai SDK), Replicate (replicate client), DeepInfra, and custom OpenAI-compatible endpoints — credentials are encrypted at rest
  • Audio pipeline: ffmpeg (ffmpeg-static) for audiobook assembly, archiver for export packaging
  • Utilities: lru-cache for in-process caching, fast-xml-parser for EPUB/XML parsing, uuid for identifier generation, zod for schema validation

External compute worker (optional)

Standalone worker package:

  • @openreader/compute-worker — standalone Node.js compute service containing its private inference and queue runtime
    • ONNX runtime: onnxruntime-node with @huggingface/tokenizers
    • Whisper alignment: onnx-community/whisper-base_timestamped (q4) for word-level timestamps
    • PDF layout: Bei0001/PP-DocLayoutV3-ONNX for document block detection and layout parsing
    • PDF rendering: pdfjs-dist, @napi-rs/canvas for server-side page rasterization
    • Utilities: jszip, ffmpeg-static
  • HTTP server: Fastify v5 with a versioned OpenAPI contract
    • Job queue + state: NATS JetStream WorkQueue pull consumers + NATS KV (jobs.whisper, jobs.layout)
    • Storage: AWS SDK v3 S3 client for reading/writing blobs
    • Logging: Pino
    • Validation: Zod
  • The Next.js app communicates with the worker only through the versioned HTTP API generated from OpenAPI.

Tooling and testing

  • ESLint
  • TypeScript
  • Playwright end-to-end tests
  • Drizzle migration/generation scripts
  • Docusaurus documentation site (docs-site/)