Thanks for the interest. This is a solo project right now, but feedback, bug reports, and PRs are welcome.
- Report a bug: open an issue with the bug template.
- Suggest a feature: especially if the reader is missing something for deep reading.
- Try it and send feedback: textstack.app, then reach out via @Rexetdeus or the contact form on the site.
See README: Run locally. For day-to-day dev, tests, migrations, mobile and lint see local-dev.md and CLAUDE.md.
- 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 57, React Native 0.86. Match web patterns where possible.
- Editor — optional. Neovim users: mrviduus/nvim-config
is a Visual Studio-style LazyVim setup;
projects/textstack.lazy.luathere matches this repo's formatting (C# via Roslyn likedotnet formatin CI, no format-on-save for the frontend).
- 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 OpenAI; 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
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
Thanks for being here.