Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

1,353 Commits

Folders and files

NameName
Last commit message
Last commit date

TextStack

Live — textstack.appLicense: AGPL v3.NETDockerPRs WelcomeAndroid — closed betaGitHub stars

TextStack — select any technical phrase, get a 2-3 sentence explanation in your native language

Finish English technical books in your native language.
Select any term → 2-3 sentence explanation that knows the book's domain. A modern Kindle Word Wise, built for dense tech reading.

Open TextStack — read books in English with native-language translationJoin the TextStack Android closed beta

The Android app is in closed testing and looking for readers. Join, keep it installed, read something.
That is the whole job — Google needs 12 testers for 14 days before it can go public.

TextStack — read books in English with translation · Why I built it · @Rexetdeus

⭐ Star the repo if you've ever abandoned a technical book mid-way — it's the strongest signal that this kind of tool is worth building.


The problem

I quit Designing Data-Intensive Applications three times. Not because it's hard — I understood most of what was on the page. The problem was the rest: unfamiliar terms that broke the flow. Eventual consistency. Attention mechanism. B-tree. Writing each one down to look up later works until you have 40 of them and you've lost the thread anyway.

Summarizing books away defeats the point. The only way to get deep understanding is to read them — but the friction has to go.

What TextStack does

Tap any term → translation in your native language, aware of the book's domain. Tap "attention" in an ML book and you get увага (механізм у нейромережах) in Ukrainian or внимание (механизм в нейросетях) in Russian — not the everyday meaning of the word. Explanation mode (no translation) is also available for native English readers who want the term clarified instead of translated. Powered by OpenAI gpt-4.1-nano, swap-in friendly — any ILlmService impl works. 18+ target languages supported, with Russian and Ukrainian as the focus during current development.

Terms you don't recognize enter a capped weekly SRS queue — no infinite backlog, no guilt. Common words and the top 15K English words are filtered out; only technical vocabulary gets surfaced.

Other toolsTextStack
Dictionary translation, word-by-wordContext-aware translation that knows the domain
Infinite SRS queueCapped weekly — no review spiral
Generic content for casual learnersBuilt for dense technical books
Static Kindle Word Wise (2014)LLM-powered (2026), 18+ target languages

Try it

  1. textstack.app — sample chapters open without signup.
  2. Tap any word you don't recognize.
  3. That's the whole pitch.

Features

Reader

  • Kindle-like experience — themes (light/sepia/dark), fonts, fullscreen, keyboard shortcuts
  • Explain — select any technical phrase → 2-3 sentence explanation in your native language, aware of the book's domain. Uses OpenAI gpt-4.1-nano. Includes a concrete analogy when the term is technical (see GIF above).
  • Text selection extras — contextual translation in 18+ languages, dictionary fallback (Free Dictionary API), highlights
  • TTS — Edge TTS via direct WebSocket (200+ voices, 0.75×–2.0× speed, two- layer cache)
  • Offline reading — PWA with IndexedDB caching, download manager

Vocabulary SRS

  • Auto-added while reading — sentence context, definition, translation
  • 5 stages (New → Recognition → Recall → Context → Mastered)
  • Capped weekly queue + LLM-generated distractors and hints (Ollama gemma4:e2b)
  • Review modes: multiple choice, classic flashcard

Library

  • 1,500+ curated technical and classic books (starter corpus, self-hostable)
  • Your own uploads — EPUB / PDF, auto-parsed with metadata enrichment
  • PDF content-quality pipeline — heuristic extraction first (instant, readable), then a gated Claude pass cleans flagged chapters in the background (running headers, fragmented paragraphs, line-wrap hyphens). Every fix is logged so deterministic rules can absorb recurring patterns and Claude usage trends down. See architecture.
  • Reading progress sync, bookmarks, highlights, reading stats

Mobile

  • React Native (Expo), Android on Google Play
  • Offline-first, same UX as web

Admin (textstack.dev)

  • Book/author/genre CRUD, chapter editor, ingestion queue
  • SSG rebuild, auto-publish, SEO backfill

MCP server

TextStack is also a Model Context Protocol (MCP) server — connect it to Claude Desktop, Cursor, or ChatGPT and your AI client can search the library, read chapters, ask grounded questions, and manage your highlights and vocabulary. Run it locally (dotnet tool install -g TextStack.Mcp) or point a client at the hosted endpoint https://textstack.app/mcp.

Setup, the 7 tools, auth, and troubleshooting: docs/05-features/mcp.md.


Tech stack

LayerTechnology
BackendASP.NET Core (.NET 10), Minimal APIs
DatabasePostgreSQL 16 + EF Core (snake_case)
SearchPostgreSQL FTS
WebReact 19, Vite, pnpm
MobileReact Native (Expo 55)
LLMOpenAI gpt-4.1-nano (explanations + translation) + Ollama gemma4:e2b (distractors, local)
TTSEdge TTS (WebSocket, no API key)
SSGPuppeteer prerender, nginx serves static first
TelemetryOpenTelemetry → Aspire Dashboard
InfraDocker Compose, Cloudflare Tunnel, nginx

Architecture: API → Application → Domain ← Infrastructure (modular monolith). Worker runs ingestion + SRS scoring + SSG jobs.


Quick start

git clone https://github.com/mrviduus/textstack
cd textstack
cp .env.example .env # edit with real values
docker compose up --build # ~3 min cold start
ServiceURL
Webhttp://localhost:5173
APIhttp://localhost:8080 · Scalar docs
Adminhttp://localhost:81
Aspire (opt-in)http://localhost:18888docker compose --profile observability up

Prerequisites: Docker, .NET 10 SDK, Node.js 20+, pnpm.


Development

# Local dev (no Docker)
dotnet run --project backend/src/Api
pnpm -C apps/web dev # http://localhost:5173
pnpm -C apps/admin dev # http://localhost:81# Mobilecd apps/mobile && npx expo start
# Tests
dotnet test# backend (unit + integration + extraction + search)
pnpm -C apps/web test# Vitest
pnpm -C apps/web test:e2e # Playwright# Lint / format
dotnet format textstack.sln

Full command reference: CLAUDE.md.


Ops / self-hosting


Contributing

Feedback, bug reports, and PRs welcome. See CONTRIBUTING.md (if it exists yet — otherwise open an issue and we'll sort it out).

Star the repo if this resonates. That's the only signal I have right now that I'm building the right thing.


License

Why AGPL? TextStack is built to be self-hosted and modified freely by individuals, teams, and small communities. AGPL ensures that if someone runs a modified version as a public service, those modifications are shared back. If your organization needs a non-AGPL license for a commercial fork or hosted product, see the commercial license note below.

GNU Affero General Public License v3.0 © 2026 Vasyl Vdovychenko.

TextStack is free and open-source software. You may use, modify, and self-host it freely for personal, internal, or community purposes. If you modify TextStack and run it as a network-accessible service, AGPL-3.0 requires you to publish your modifications under the same license.

Commercial license available for organizations that need to use TextStack without AGPL obligations (e.g. proprietary forks, hosted commercial services). Contact: mrviduus@gmail.com.

  • Source code: AGPL-3.0
  • Standard Ebooks corpus (included in seed data): CC0 / public domain
  • Edge TTS: used under Microsoft's Edge Read Aloud terms
  • Third-party deps: their respective licenses

Why the name

A stack of books. A stack of text. Read through it.

About

A reader that helps you finish dense tech books. Contextual word explanations, capped weekly SRS, offline reading. EPUB / PDF / FB2. ASP.NET Core + React + Expo.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

27 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages