Skip to content

Latest commit

 

History

99 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ohara banner

A mobile-only, single-user read-later app. Save a link. Get it extracted and AI-summarized on-device. Read it later.

React Native Expo TypeScript Platform SQLite Private

WhyArchitectureProject layoutRunningGit workflow


Why

No backend, no account, no server bill. Everything — storage, extraction, AI enrichment, backup — runs on the phone. Built for one person's reading list, not a product.


Architecture

Concern Approach
Storage On-device SQLite (expo-sqlite) — a single content table plus a settings table (theme, etc).
Extraction On-device. Articles via node-html-parser (fetch HTML, pull og:* meta + main content). YouTube via the public oEmbed endpoint — no duration/transcript, since there's no client-side yt-dlp equivalent.
AI enrichment Summary + topics, called directly from the app (OpenAI or Gemini, picked by EXPO_PUBLIC_AI_PROVIDER) using an embedded API key. Acceptable only because this is a private, single-user build — never distribute the APK with a real key baked in.
Search & tags LIKE-based full-text search plus freeform tags, both stored as plain SQLite columns — no FTS5, no new table, sized to a personal library.
Reading extras Scroll-position resume (fraction of content height) and a quote/note highlight list per item — not inline text-selection highlighting.
Backup / sync Mihon-style JSON export of the whole library, and import of either a full backup or a plain [{url, contentType?}] list (e.g. hand-written on a PC, imported via Settings → Import from file). No server, no relay.

Spec source of truth lives in openspec/specs/. Read it before changing behavior — see CLAUDE.md.


Project layout

mobile/               Expo Router app (this is what you build/run)
  app/                screens (index, capture, content/[id], settings, stats)
  src/api/content.ts  capture/list/get/search/archive/tags — same interface pre- and post- backend removal
  src/db/             sqlite tables + repositories
  src/extraction/     article + youtube extractors, reading time
  src/ai/enrich.ts    AI summary/topics call
  src/processing/     pending -> ready pipeline, stuck-row sweep on launch
  src/backup/         export/import
backend/              retired; no longer called by the app
openspec/             specs + change history (source of truth for product behavior)

Running

Setup steps
cd mobile
npm install
npx expo run:android   # or run:ios

Requires mobile/.env (see mobile/.env.example):

EXPO_PUBLIC_AI_PROVIDER=gemini      # or "openai"
EXPO_PUBLIC_GEMINI_API_KEY=
EXPO_PUBLIC_OPENAI_API_KEY=

Must be UTF-8, not UTF-16. Notepad/PowerShell saves sometimes write UTF-16LE, which Expo can't read.


Git workflow

Each OpenSpec change gets its own branch off main, merged back with --no-ff once done. Never commit feature work directly to main. See CLAUDE.md.

About

A content-first reading companion for everything you discover online.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages