Thanks for the interest. This is a solo project right now, but feedback, bug reports, and PRs are welcome.
- ⭐ Star the repo — the strongest signal I have about whether this is useful.
- 🐛 Report a bug — open an issue with the bug template.
- 💡 Suggest a feature — especially if you're reading AI/ML books and the reader is missing something.
- 📝 Try it + send feedback — textstack.app, then ping me on @Rexetdeus or the contact form on the site.
See the README Quick start. Everything runs in
Docker via docker compose up --build.
For day-to-day dev without Docker, see CLAUDE.md — full command reference (tests, migrations, mobile, lint).
- Open an issue first if the change is > ~30 LoC or touches multiple files. Cheaper to align on direction than on code.
- Branch from
mainwith a descriptive name:feat/<short>,fix/<issue>,docs/<area>,refactor/<area>,test/<what>. - Tests — add/update tests for the behavior you changed.
dotnet test # backend (unit + integration + extraction + search) pnpm -C apps/web test # web unit (Vitest) pnpm -C apps/web test:e2e # Playwright (needs services up)
- Lint —
dotnet format textstack.slnfor backend. Web/admin have no enforced formatter yet; match surrounding style. - Conventional commit subject —
type(scope): summary. Common types:feat,fix,refactor,docs,presale. One logical change per commit; rebase locally if things got noisy.
- Title: short, imperative, < 70 chars.
- Body: follow the template (filled automatically when you open the PR).
- Scope: one concern per PR. Drive-by refactors go in a separate PR.
- Breaking changes — call them out. Include a migration note.
- Screenshots / GIFs for UI changes. Required, not optional.
- Backend — idiomatic C# / .NET 10. Minimal APIs, EF Core. Snake-case
in DB (handled by EF naming convention). Nullable-aware. Test naming:
{Method}_{Scenario}_{Expected}. - Frontend — React 19 functional components, hooks. CSS variables for theming (no CSS-in-JS). No Redux/Zustand — React Context is enough.
- Mobile — Expo 55, React Native 0.83. Match web patterns where possible.
- Reader UX — smooth scroll, fast word-tap response, offline works.
- SRS quality — capped queue, anti-spiral tiers, explanations that actually help the reader.
- Performance — ingestion speed, SSG prerender time, reader cold-start.
- Legal hygiene — only public domain / CC0 / user-owned content.
- Scope creep that doesn't serve deep reading.
- Adding new LLM providers just to have them — we have Ollama (local) and plans for Claude; keep that surface small.
- Reintroducing features I deliberately removed.
backend/src/
Api/ # Minimal APIs, middleware
Application/ # Business logic, interfaces
Domain/ # Entities, enums (pure C#)
Infrastructure/ # EF Core, storage, adapters
Worker/ # Ingestion + SSG polling + GC
Extraction/ # EPUB/PDF parsers
Search/ # Postgres FTS (Meilisearch provider optional)
apps/
web/ # Public reader (React + Vite)
admin/ # Admin panel (React + Vite)
mobile/ # Mobile app (Expo)
Deeper detail: docs/01-architecture/.
By submitting a pull request to this repository, you agree that:
- Your contribution is your original work or you have the right to submit it under the project license.
- Your contribution is licensed under AGPL-3.0, the same license as the rest of the project.
- You grant Vasyl Vdovychenko (the project copyright holder) a perpetual, worldwide, non-exclusive, royalty-free license to relicense your contribution under any license, including commercial proprietary licenses, for the purpose of dual-licensing TextStack to commercial customers.
This CLA exists so the project can offer commercial licenses alongside the AGPL-3.0 community version, which helps fund continued development.
If you do not agree with this CLA, do not submit pull requests. You can still file issues, fork the project, and run your own version under AGPL-3.0.
Be kind. Assume good faith. That's it.
- Twitter: @Rexetdeus
- Email via textstack.app contact form
- GitHub Discussions (broader questions)
Thanks for being here.