A local-first reading app that treats the last page as the product.
React 19 · Next.js 16 · TypeScript · Tailwind 4 · Prisma + SQLite · PDF.js
People don't abandon books at a bad chapter. They abandon them when the habit dies.
One missed day becomes three. Three becomes "I'll restart next month." Meanwhile every e-reader on earth shows you the same sterile thing: a percentage. A number that shames you instead of moving you.
Athena is built on a different contract:
Your library lives on your machine, and the app's only job is to get you back on the rail today.
The rail — el riel — is a segmented progress track that lives under every book. It has milestones, it has a streak, it tells you the honest ETA to the final page, and it throws confetti when you cross a milestone. Not gamification noise. One clear instrument, tuned for consistency.
| The library at night — egean blue | The library by day — marble morning |
|---|---|
![]() |
![]() |
| Teleprompter — one stream, letter by letter | The same stream by day — the type is yours (A− / A+) |
|---|---|
![]() |
![]() |
- Rail + streak + ETA under every book — honest progress, not a percentage.
- Teleprompter — one continuous stream, letter by letter, font
0.8×–1.6×, rewind with←. - Immersion — UI hides on idle (
H), fullscreen with wider measure, teleprompter controls fade out. - EPUBs & PDFs paginated the same way (~320 words/virtual page); rail and header track real pages.
- Literature settings — X-ray, outline, dictionary, natural pauses, argument skeleton, locked notes, dual read.
- ES / EN / PT — interface, dates, everything switches.
- Home copy — pull/push your library and progress between the Android app and your own server over your home network, always by hand (Amendment 1: no cloud, no accounts, silent degradation).
- Neo-brutalist UI — zero radius, hard 2px borders, offset shadows, buttons that press.
- Offline-first — your library lives on your machine (data home at
~/.local/share/athena), never on someone else's server.
Prerequisites: Bun (it replaces Node + npm), any modern browser. Internet is only needed for the install and the first OCR language download — reading works offline.
Download athena_<version>_amd64.deb from
releases and:
sudo apt install ./athena_<version>_amd64.deb # app in /opt/athena + `athena` on your PATH
athena init # first time only: data home + schema
athena start # → http://localhost:3000 (LAN mode: athena start --lan)The package ships the production build — nothing recompiles. Your data lives
in the data home (~/.local/share/athena), so updates and removals never
touch a single book.
git clone https://github.com/MoriNo23/Athena && cd Athena
docker compose up -d --buildAthena-<version>-linux-x64.tar.gz from
releases: unpack it and follow
the COMO-ARRANCAR.txt inside — no compilation, straight to reading.
Athena-v<version>.apk from
releases: the same app in a
WebView with an offline engine that mirrors the whole experience on-device —
including the home copy: pull or push your library and progress to your
own computer over the home network, always by hand.
Guide and limits in docs/APK-OFFLINE.md (Spanish).
git clone https://github.com/MoriNo23/Athena.git
cd Athena
cp .env.example .env # one line: DATABASE_URL=file:../db/custom.db
bun install # also runs prisma generate (postinstall)
bunx prisma db push # creates the empty SQLite library on first run
bun run dev # → http://localhost:3000Drop a PDF or EPUB on the library. That's the whole onboarding.
Sizes: each book can weigh up to 200 MB (PDF or EPUB). The lock (
src/proxy.ts) never clips the upload:next.config.tsraises the proxy body cap (experimental.proxyClientMaxBodySize, 10 MB default in Next 16) to 256 MB so heavy books reach the API whole. Above 200 MB the API answers 413 with a friendly notice.
Why
file:../db/custom.db? Prisma resolves the SQLite path relative toprisma/, so this single line lands the library at<repo>/db/custom.dbon any machine — no edits, no absolute paths, noprisma/db/strays.
Everyday scripts:
| Command | What it does |
|---|---|
bun run dev |
Dev server on port 3000 |
bun run build + bun run start |
Optional production mode |
bun run lint |
ESLint pass |
bun run db:push |
Apply Prisma schema changes |
bun run athena |
House CLI: init · start · doctor · backup · home |
Your books, covers and progress live outside the code: new installs keep
them in the data home (~/.local/share/athena, overridable with
ATHENA_HOME); the classic in-repo layout (db/ + public/uploads/) still
works. They are gitignored on purpose: your library never leaves your
machine.
- docs/INDICE.md — the Spanish documentation hub: installation, reading guide, folder library, settings, self-hosting, Android APK and troubleshooting.
- docs/PRODUCT.md — the product constitution (Spanish).
- docs/SECURITY.md — APK keystore risk, mitigations and the rotation recipe (Spanish).
- docs/SELFHOSTING.md — self-hosting deep dive: Docker, LAN mode, data home, Caddy, backups (Spanish).
Everything a clone must pass before a release or a pull request — run them from the repo root, in this order:
bunx tsc --noEmit # 0 type errors
bun run lint # 0 errors, 0 warnings
bun test # full suite green (the CI workflow enforces all three)
bun run build # production build compilesMIT — clone it, modify it, self-host it. Your library stays yours.
ATHENA — the rail takes you to the last page.



