KoeYomi is a mobile manga reader built with Expo + React Native focused on a smooth reading experience, offline chapter downloads, and local persistence with SQLite.
Current app configuration version: 1.1.2 (app.json).
- Search manga titles through a backend connected to MangaDex.
- Open manga details with title, status, author, genres, and synopsis.
- Switch chapter language between available translations (
en,es-lain current UI logic). - Save and remove favorites locally.
- Download chapters for offline reading.
- Persist reading progress per chapter.
- Track reading history with timestamps.
- Configure reader and data preferences (language, mode, direction, paging, quality, data saver) with local persistence.
- Manage downloaded manga/chapter files from in-app storage management screens.
- Reader gestures: single-tap UI toggle, pinch-to-zoom, pan, and double-tap zoom.
| Home Screen | Manga Details Screen | Search Screen |
|---|---|---|
![]() |
![]() |
![]() |
| Screen to show your favorites | Details of the selected manga | Search layout |
| Records Screen | Settings Screen | About Screen |
|---|---|---|
![]() |
![]() |
![]() |
| Your read history in the app | Change settings of the app | App information |
- React 19
- React Native 0.83
- Expo SDK 55
@expo/ui(Jetpack Compose components for updated Android UI controls)- Expo Router (file-based routing)
- Expo SQLite
- AsyncStorage (settings persistence)
- React Native Reanimated + Gesture Handler
- Expo Image
- Expo UI
- Expo Web Browser
- Typed
fetcherservice for API communication
The app is initialized in src/app/_layout.tsx:
- Prevents/hides splash screen at startup.
- Initializes SQLite schema through
SQLiteProvider. - Loads persisted app preferences through
SettingsProvider. - Creates tab navigation using
expo-routerTabs.
Navigation is file-based with expo-router:
- Root tabs in
src/app/_layout.tsx - Home stack group in
src/app/(home)/_layout.tsx - Settings stack group in
src/app/(settings)/_layout.tsx - Detail and reader screens are nested under
(home)
- Screens request data through
src/services/fetcher.ts. - Data is cached/persisted in SQLite (
mangas,chapters, etc.). - UI reads local data first, then fetches updates when needed.
- Reader updates history and progress while reading.
koeyomi/
├─ assets/
│ ├─ icons/
│ │ ├─ android-adaptive-icon-color.png
│ │ ├─ android-adaptive-icon.png
│ │ ├─ browser.png
│ │ ├─ check.png
│ │ └─ raw.png
│ └─ splash/
├─ src/
│ ├─ app/
│ │ ├─ (home)/
│ │ │ ├─ _layout.tsx
│ │ │ ├─ index.tsx
│ │ │ ├─ manga/
│ │ │ │ └─ [mangaId].tsx
│ │ │ └─ reader.tsx
│ │ ├─ (settings)/
│ │ │ ├─ _layout.tsx
│ │ │ ├─ index.tsx
│ │ │ ├─ preferences.tsx
│ │ │ ├─ about.tsx
│ │ │ └─ (storageManager)/
│ │ │ ├─ _layout.tsx
│ │ │ ├─ index.tsx
│ │ │ └─ manga/
│ │ │ └─ [mangaId].tsx
│ │ ├─ _layout.tsx
│ │ ├─ history.tsx
│ │ ├─ search.tsx
│ ├─ components/
│ │ ├─ home/
│ │ ├─ manga/
│ │ └─ ui/
│ ├─ context/
│ │ └─ appContext.tsx
│ ├─ services/
│ │ ├─ fetcher.ts
│ │ ├─ getTitle.ts
│ │ └─ mangaFunctions.ts
│ ├─ types/
│ │ ├─ chapters.ts
│ │ ├─ favorites.ts
│ │ ├─ mangas.ts
│ │ ├─ records.ts
│ │ └─ searchs.ts
│ ├─ constants.ts
│ └─ theme.ts
├─ app.json
├─ eas.json
├─ package.json
└─ tsconfig.json
- Node.js (recommended LTS,
>=20) - npm
- Android Studio + emulator/device (recommended primary target)
- EAS CLI (optional, for cloud builds)
npm installnpx expo startCreate .env or .env.local in the project root:
EXPO_PUBLIC_KOEYOMI_BACKEND=https://your-backend-domain.com
EXPO_PUBLIC_MANGADEX_UPLOADS=https://uploads.mangadex.org
EXPO_PUBLIC_MYANIMELIST_BASE_URL=https://myanimelist.netNotes:
EXPO_PUBLIC_KOEYOMI_BACKENDis required for search/manga/chapter endpoints.EXPO_PUBLIC_MANGADEX_UPLOADSis used to load chapter images.EXPO_PUBLIC_MYANIMELIST_BASE_URLis used for external manga links.
/(home)→ Home (library)/(home)/manga/[mangaId]→ Manga details/(home)/reader?id=<chapterId>&format=<format>&title=<title>&subtitle=<subtitle>→ Reader/search→ Search screen/history→ Reading history/(settings)→ Settings home/(settings)/preferences→ Reader/data preferences/(settings)/about→ App info and acknowledgements/(settings)/(storageManager)→ Downloaded manga list/(settings)/(storageManager)/manga/[mangaId]→ Downloaded chapter manager
npx expo start # Start Expo dev server
npx expo run:android # Run Android native projectInitialized in src/app/_layout.tsx.
users: local user identity.mangas: manga metadata and cover URL.chapters: chapter metadata, download status, local path, last page read.favorites: user ↔ manga relation.downloads: user ↔ chapter download records.records: user ↔ chapter reading history.
Indexes are created for common lookup and relation columns.
The app expects these backend routes:
GET /mangadex/search?title=<query>GET /mangadex/manga/:idGET /mangadex/manga/:id/feed?language=<lang>GET /mangadex/chapter/:id
Expected payload behavior (high-level):
- Manga entities include
attributes,relationships, andcoverImageUrl. - Chapter image payload includes
chapter.hashandchapter.dataSaver.
- Some UI feedback uses
ToastAndroid, so Android is currently the primary supported platform. - Parts of the updated UI use
@expo/uiJetpack Compose components, so Android behavior is the most validated path. - No dedicated lint/test scripts are defined in
package.jsonyet.
- Environment variables not loading
- Restart Expo with cache clear:
npx expo start -c
- Backend request errors
- Verify
EXPO_PUBLIC_KOEYOMI_BACKENDand endpoint availability.
- Verify
- Images not rendering in reader
- Validate
EXPO_PUBLIC_MANGADEX_UPLOADSand chapter hash/data payload.
- Validate
- Android run/build issues
- Confirm Android SDK setup and device detection (
adb devices).
- Confirm Android SDK setup and device detection (
Current state:
- No test runner configured.
- No lint/typecheck scripts configured.
Suggested additions:
npm run typecheckwithtsc --noEmitnpm run lintwith ESLint for React Native + TypeScript- Unit tests for
fetcherand data transformation logic
- Fork the repository.
- Create a feature branch.
- Keep changes focused and documented.
- Add/update tests when behavior changes.
- Open a Pull Request with a clear summary.
Use Conventional Commits:
feat:New featuresfix:Bug fixesrefactor:Internal code improvementsdocs:Documentation updatestest:Test changeschore:Tooling/maintenance
- Follow the existing code style and conventions
- Test on both Android emulator and physical device
- Update documentation for new features
- Add TypeScript types for new code
- Keep PRs focused on a single feature/fix
- Write clear commit messages
- All PRs require at least one approval
- No merge conflicts
- Code follows project conventions
This project is licensed under the MIT License. See the LICENSE file for full details.
- MangaDex data/image flow is powered through MangaDex-compatible backend routes.
- Expo - For the excellent React Native framework
react-native-zoom-reanimatedinspiration/derived portions are credited inLICENSE.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: stivenpilca@gmail.com





