
- JavaScript99.6%
- HTML0.4%
Read deeply. Think clearly. Remember what matters.

A reading-focused web app with text and article import, a focus mode that dims surrounding paragraphs, guided questions, and a reflection archive.
Most reading software optimizes for one metric: time on screen. The result is an environment filled with progress bars, streaks, recommendation feeds, and pop-up encouragement — tools designed to retain your attention, not support your comprehension.
From README.md in the repository.
Read deeply. Think clearly. Remember what matters.
A frictionless, e-ink-inspired reading environment built for comprehension — not consumption.
Live Demo · Report a Bug · Request a Feature · Roadmap
Most reading tools are built to keep you reading more. CalmReader is built to help you understand better — one passage at a time, without notifications, streaks, or noise.
Most reading software optimizes for one metric: time on screen. The result is an environment filled with progress bars, streaks, recommendation feeds, and pop-up encouragement — tools designed to retain your attention, not support your comprehension.
The neuroscience tells a different story. Comprehension depends on working memory — a small, effortful workspace that holds ideas in active relation to each other. Every interruption taxes that workspace. Distraction isn't a minor annoyance; it's the mechanism by which understanding fails to form.
CalmReader is the antithesis of that design pattern. It is a page built like a well-made notebook: it loads your text, gets out of the way, and trusts you to read slowly. When you encounter a hard concept, it surfaces a definition — inline, quietly — without sending you down a browser tab rabbit hole. When you finish a section, it asks one good question instead of offering a five-star rating prompt.
It does not want you to keep using it. It wants you to finish reading.
CalmReader is grounded in Calm Technology principles articulated by Mark Weiser and John Seely Brown: technology should require only as much attention as it deserves, communicate information at the periphery rather than the center, and amplify the best of human capability.
In practice, this means:
Bring your own content. Paste raw text directly, upload a .txt or .md file, or pull in any article via URL using the Jina Reader proxy. No account required. No content library. Just your text.
As you read, paragraphs outside your current position softly dim — reducing visual noise and keeping your working memory focused on one idea at a time. Enable it when you want it. Disable it when you don't.
CalmReader doesn't summarize — it questions. When you tap a paragraph, a context-aware prompt appears in the margin: "Does the conclusion necessarily follow?" or "What would someone who disagrees say?" These aren't generic questions. They're selected based on what the paragraph is doing — making a causal claim, citing evidence, or issuing a value judgment.
Your answer goes into the Wisdom Ledger. Not the AI's summary. Yours.
Forty-plus academic and conceptual terms are quietly annotated beneath the surface. Tap a term — neuroplasticity, heuristic, externality — and its definition expands inline. Reading continues. You never leave the page.
A running log of insights you've written during a session. Every entry is authored by you, not generated. The ledger is searchable, exportable, and stored locally.
Every insight and Pause Point response is saved across sessions in localStorage/IndexedDB. Search your own thinking across every text you've ever read in CalmReader: type a concept and find the thought you had about it three months ago.
Every six paragraphs, a quiet interstitial appears: "Without looking back — what do you remember?" A small text field invites active recall, which cognitive science identifies as one of the most reliable mechanisms for long-term retention. Not a quiz. Not a score. A question.
Warm paper tones (#F9F6F0), generous line height, and two typefaces chosen for reading: Literata for body text and Atkinson Hyperlegible for UI — a typeface designed by the Braille Institute to maximize legibility for readers with low vision.
Screenshots coming soon. In the meantime, try the live demo.
| Import Screen | Reading View | Socratic Margin |
|---|---|---|
![]() |
![]() |
![]() |
| Wisdom Ledger | Reflection Archive | Mobile View |
|---|---|---|
![]() |
![]() |
![]() |
# Clone the repository
git clone https://github.com/yourusername/calmreader.git
cd calmreader
# Install dependencies
pnpm install
# Start the development server
pnpm dev
Open http://localhost:5173 and paste any text to begin.
pnpm build
pnpm preview
The production build outputs to dist/ and is deployable to any static host (Vercel, Netlify, Cloudflare Pages).
CalmReader has no backend and requires no environment variables for local development. Everything runs in the browser.
# Development server with hot module replacement
pnpm dev
# Type checking (if using TypeScript migration branch)
pnpm typecheck
# Lint
pnpm lint
# Run all checks before committing
pnpm check
CalmReader uses two storage mechanisms:
| Scope | Mechanism | Purpose |
|---|---|---|
| Session insights | useState |
Current reading session only |
| Reflection archive | localStorage |
Persists across sessions, searched globally |
The storage layer is abstracted behind a simple adapter interface, designed for future migration to IndexedDB (larger archives) or native SQLite (desktop/mobile). See packages/core/src/storage/ for details.
The URL import feature proxies requests through Jina Reader (https://r.jina.ai/{url}). No API key is required. This makes no requests unless you explicitly use the Link tab — and it is the only network call CalmReader ever makes after the initial page load.
calmreader/
├── src/
│ ├── CalmReader.jsx # Root component — all reading UI
│ ├── main.jsx # React entry point
│ ├── storage/
│ │ ├── adapter.ts # StorageAdapter interface
│ │ ├── idb.ts # IndexedDB implementation
│ │ └── index.ts # Platform detection, exports adapter
│ ├── lib/
│ │ ├── parser.js # parseImportedText, buildSegments
│ │ ├── prompts.js # SOCRATIC_BANK, getPromptForParagraph
│ │ └── terms.js # TERM_DICTIONARY (X-Ray definitions)
│ └── assets/
│ └── fonts/ # Bundled Literata + Atkinson Hyperlegible
│
├── public/
│ ├── manifest.json # PWA manifest
│ └── sw.js # Service worker (offline support)
│
├── docs/
│ └── screenshots/ # README images
│
├── index.html
├── vite.config.js
├── package.json
└── README.md
Single-file component architecture. CalmReader.jsx is intentionally large. This is not technical debt — it is a deliberate reflection of the product's philosophy. One text. One session. One file. Splitting it into twenty micro-components would add navigation overhead with no user benefit.
No state management library. CalmReader uses only useState, useEffect, useMemo, and useRef. The state surface is small enough that Redux or Zustand would be ceremony, not architecture.
No UI component library. Every visual element is hand-crafted with inline styles. This keeps the design system tight, makes the palette explicit, and means there are no Tailwind or MUI overrides to fight against.
CalmReader is being developed with the principles of the deployment strategy already in mind. Each platform phase shares the same core — no parallel codebases.
Contributions are welcome. CalmReader is a small, focused project — please keep that spirit in mind when proposing changes.
# Fork the repository and clone your fork
git clone https://github.com/yourusername/calmreader.git
# Create a feature branch
git checkout -b feature/your-feature-name
# Make your changes, then run checks
pnpm check
# Commit with a clear message
git commit -m "feat: add custom glossary support for X-Ray terms"
# Push and open a pull request
git push origin feature/your-feature-name
src/lib/terms.js)src/lib/prompts.js)CalmReader draws on ideas from people who thought seriously about attention, typography, and the design of quiet tools:
MIT License — see LICENSE for details.
You are free to use, modify, and distribute CalmReader. If you build something with it, the only thing we'd ask is that you keep the spirit of the project intact: no dark patterns, no engagement optimization, no noise.
"A page that disappears is the highest compliment a reading tool can receive."
GitHub data synced 25 Oct 2026