Thank you for your interest in contributing to DexReader! This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Getting Started
- Development Workflow
- Code Standards
- Commit Message Guidelines
- Pull Request Process
- Project Architecture
- Testing
- Project Documentation
📢 Help Wanted: We're looking for Mac users to help test DexReader! See the Testing section for details. No coding required—just download, try it out, and report your experience.
This project adheres to a Code of Conduct that all contributors are expected to follow. Please read CODE_OF_CONDUCT.md to understand what behaviours are expected and what will not be tolerated.
- Node.js: Version 24.x or later
- npm: Version 11.x or later (comes with Node.js)
- Git: For version control
- Code Editor: We recommend VS Code, as we have some project-level settings, and extensions recommendation that would make your development experience smoother, but feel free to use other editor of your choice
- Database Management tool (optional): We use SQLite 3 as the local database for the app, which you can easily inspect the database using said tool. It's not required to work with the app, but having it should allows you an easier time debugging database code should you ever need to
-
Fork and Clone
git clone https://github.com/YOUR_USERNAME/DexReader.git cd DexReader -
Install Dependencies
npm install
-
Set Up Git Hooks
Git hooks are automatically installed via Husky during
npm install. These hooks enforce:- Code formatting (Prettier)
- Linting (ESLint)
- Commit message conventions (commitlint)
-
Run Development Server
npm run dev
The app will launch in development mode with hot reload enabled.
| Command | Description |
|---|---|
npm run dev |
Start development server with hot reload |
npm run build |
Build for production (no packaging) |
npm run lint |
Run ESLint to check code quality |
npm run typecheck |
Run TypeScript type checking |
npm run format |
Format all code with Prettier |
npm run build:win |
Build Windows installer (requires Windows) |
npm run build:mac |
Build macOS DMG (requires macOS) |
npm run build:linux |
Build Linux packages (AppImage, Deb, Snap) |
Always create a new branch for your work:
git checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-descriptionRecommended branch naming conventions (feel free to use your own if you prefer):
feature/*- New featuresfix/*- Bug fixesdocs/*- Documentation changesrefactor/*- Code refactoringperf/*- Performance improvementstest/*- Adding or updating tests
The project doesn't enforce specific branch names convention, but using descriptive names helps everyone understand what you're working on.
-
Write Code
- Follow the Code Standards
- Write clear, self-documenting code
- Add comments for complex logic
-
Test Your Changes
- Run
npm run devand manually test - Ensure no TypeScript errors:
npm run typecheck - Fix any linting issues:
npm run lint
- Run
-
Format Code
- Run
npm run formator let pre-commit hooks handle it
- Run
Use British English consistently throughout the codebase:
- "Favourites" (not "Favorites")
- "Colour" (not "Color")
- "Organise" (not "Organize")
- "Centre" (not "Center")
- Tone: Casual and friendly (avoid corporate jargon)
- Error Messages: Clear, actionable, and friendly
- Good: "Oops! Couldn't load that chapter. Check your internet connection?"
- Bad: "An error occurred while loading the requested resource."
- Use Contractions: can't, won't, it's, etc.
- Icons: Always use Fluent UI icons (
@fluentui/react-icons) - never use unicode emoji in code
- Strict Mode: Always enabled - no implicit
anytypes - Explicit Types: Prefer explicit return types for functions
- Interfaces: Use for public APIs and component props
- Type Aliases: Use for unions, complex types, and utility types
- Prefer
undefinedovernull: Useundefinedfor absent optional values- Exception: React
useStatehooks commonly initialize withnull - Exception: When
nullhas semantic meaning (e.g., "explicitly cleared" vs "not set") - Exception: External APIs or libraries that expect
null - Exception: JSON serialization where
undefinedis omitted
- Exception: React
- Null Safety: Handle both
nullandundefinedexplicitly when they can occur
Example:
// Good - Prefer undefined for optional values
interface MangaSearchParams {
query: string
limit?: number // Will be undefined if not provided
tags?: string[] // Will be undefined if not provided
}
function searchManga(params: MangaSearchParams): Manga[] | undefined {
// Return undefined if no results (not null)
return results.length > 0 ? results : undefined
}
// Acceptable - React state commonly uses null
const [selectedManga, setSelectedManga] = useState<Manga | null>(null)
// Good - Explicit typing
interface MangaListProps {
manga: Manga[]
onSelect: (id: string) => void
}
export function MangaList({ manga, onSelect }: MangaListProps): JSX.Element {
// Implementation
}
// Avoid - Implicit any
function MangaList(props) {
// Implementation
}- Functional Components: Always use function components (no class components)
- Hooks: Follow Rules of Hooks
- Component Files: One component per file
- Props Destructuring: Destructure props in function parameters
- Event Handlers: Prefix with
handle(e.g.,handleClick,handleSubmit)
src/
├── main/ # Electron main process
│ ├── api/ # MangaDex API client
│ ├── database/ # Database schemas and queries
│ ├── ipc/ # IPC handlers
│ ├── services/ # Business logic
│ └── utils/ # Utility functions
├── preload/ # Electron preload scripts
└── renderer/ # React frontend
└── src/
├── components/ # React components
├── hooks/ # Custom React hooks
├── stores/ # Zustand state stores
├── types/ # TypeScript type definitions
└── utils/ # Frontend utilities
- Files: kebab-case (e.g.,
manga-list.tsx,use-fetch-manga.ts) - Components: PascalCase (e.g.,
MangaList,ChapterReader) - Functions: camelCase (e.g.,
fetchManga,handleClick) - Constants: UPPER_SNAKE_CASE (e.g.,
MAX_CACHE_SIZE,API_BASE_URL) - Interfaces: PascalCase with descriptive names (e.g.,
MangaListProps,ApiResponse) - Types: PascalCase (e.g.,
MangaId,ChapterStatus)
This project uses Conventional Commits enforced by commitlint. All commit messages must follow this format:
<type>(<scope>): <subject>
<body>
<footer>
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bug fix |
docs |
Documentation changes |
style |
Code style changes (formatting, whitespace) |
refactor |
Code refactoring (no functional changes) |
perf |
Performance improvements |
test |
Adding or updating tests |
build |
Build system or dependency changes |
ci |
CI/CD configuration changes |
chore |
Maintenance tasks (no production code changes) |
# Feature
feat(reader): add double-page spread mode
# Bug fix
fix(download): prevent duplicate downloads for same chapter
# Documentation
docs(readme): update installation instructions for Linux
# Refactoring
refactor(api): simplify rate limiter implementation
# Performance
perf(database): add index for chapter queriesCommon scopes:
reader- Chapter reader componentlibrary- Library/favourites managementdownload- Download functionalityapi- MangaDex API integrationdatabase- Database operationsui- UI components
- Use imperative mood ("add" not "added" or "adds")
- Don't capitalize first letter
- No period at the end
- Maximum 72 characters
-
Update Your Branch
git fetch origin git rebase origin/main
-
Run All Checks
npm run lint npm run typecheck npm run build
-
Test Thoroughly
- Manual testing in development mode
- Test on your target platform (Windows/macOS/Linux)
- Verify no regressions in existing functionality
-
Push Your Branch
git push origin feature/your-feature-name
-
Open PR on GitHub
- Fill out the PR template completely
- Write a clear description of changes
- Reference any related issues (e.g., "Closes #123")
- Add screenshots for UI changes
-
PR Title: Must follow conventional commit format
- Example:
feat(reader): add double-page spread mode - This is enforced by CI checks
- Example:
All PRs must pass the following checks:
- PR Title Validation: Must follow conventional commit format
- PR Description: Must include description (not just template)
- Commit Messages: All commits must follow conventional format
- Linting: ESLint must pass with no errors
- Type Checking: TypeScript compilation must succeed
- A maintainer will review your PR
- Address any feedback or requested changes
- Once approved, your PR will be merged to
main
DexReader follows Electron's multi-process architecture:
- Main Process: Node.js environment (API client, database, file system)
- Renderer Process: Chromium/React (UI, user interactions)
- Preload Scripts: Bridge between main and renderer (IPC)
Critical: MangaDex blocks direct image hotlinking. All images MUST be proxied through the main process using custom protocol handlers:
mangadex://- Online image streaminglocal-manga://- Downloaded chapter images
See docs/architecture/ for detailed information.
- Zustand: Primary state management library
- React Context: For component-scoped state
- Local State: Use
useStatefor simple component state
- Better-sqlite3: Synchronous SQLite database
- Drizzle ORM: Type-safe database queries
- Migrations: SQLite schema migrations in
src/main/database/migrations/
When you first start the app, you should see the development database located at the root of the project directory
Comprehensive documentation is available in docs/:
docs/architecture/- System architecture and design decisionsdocs/components/- UI component specificationsdocs/design/- Design system and wireframes
We're looking for Mac users to help test DexReader! No coding experience required—just download, try it out, and let us know any issues you find.
Why we need help: DexReader is developed and tested primarily on Windows and Linux. While macOS builds are generated automatically via CI/CD, they haven't been extensively tested on real Mac hardware due to device availability constraints.
How to help:
- Download the latest
.dmgfrom Releases - Install and test the core features:
- Browse and search manga
- Read chapters (single page, double page, vertical scroll modes)
- Download chapters for offline reading
- Manage your library (favorites, collections, history)
- Check for macOS-specific issues:
- Menu bar integration
- Keyboard shortcuts (Cmd vs Ctrl)
- Notifications
- Retina display rendering
- File path handling
- Report bugs on GitHub Issues
- Share your experience in Discussions
Your feedback is incredibly valuable and helps ensure DexReader works great for all Mac users! 🎉
Currently, the project relies on manual testing:
- Run the app in development mode:
npm run dev - Test your changes thoroughly
- Check both happy paths and error cases
- Verify UI responsiveness and accessibility
Automated testing (unit, integration, E2E) will be added in future phases. Contributions to establish testing infrastructure are welcome!
Update documentation when you:
- Add new features or APIs
- Change existing behavior
- Fix bugs that weren't obvious
- Add architectural decisions
- README.md: User-facing installation and usage
- CONTRIBUTING.md: This file - contributor guidelines
- docs/: Technical documentation
docs/architecture/: System design and architecturedocs/components/: Component specificationsdocs/design/: Design system and UI guidelines
- Code Comments: Explain "why", not "what"
- Use British English
- Be clear and concise
- Include code examples where helpful
- Update the
Last Updateddate in memory bank files
- Issues: Open an issue for bugs or feature requests
- Discussions: Use GitHub Discussions for questions
- Documentation: Check
docs/for architectural details
Once again, thank you for your interest in contributing to DexReader!