Maintained by @AnInsomniacy. PRs and issues are welcome!
Before you start contributing, make sure you understand GitHub flow.
git clone https://github.com/AnInsomniacy/motrix-next.git
cd motrix-next
pnpm install
pnpm tauri dev # Start dev server (Tauri + Vite)Rust backend (standalone):
cd src-tauri
cargo build
cargo testAll checks must pass before PR merge:
pnpm lint # ESLint (0 errors, 0 warnings)
pnpm test # Vitest
npx vue-tsc --noEmit # TypeScript strict mode
cd src-tauri && cargo test # Rust testsPre-commit hooks (husky + lint-staged) auto-run eslint --fix and prettier --write on staged files.
- Keep
<script>logic under 300 lines. Extract composables when approaching this limit. Template and scoped CSS may exceed this — Naive UI components often require extensive style overrides. - Use
<script setup lang="ts">with composition API. - Every file starts with a
/** @fileoverview ... */doc comment. - Use
loggerfrom@shared/loggerfor all runtime logging — no bareconsole.*.
- TypeScript: Never leave
catchblocks empty — always calllogger.debug()at minimum. - Rust: Use the
AppErrorenum (Store,Engine,Io,NotFound,Updater,Upnp) for all command return types.
- Follow TDD (Red → Green → Refactor) for new utilities and guards.
- Test files live alongside source:
__tests__/filename.test.ts. - Runtime type guards (in
guards.ts) validate all external API responses.
First you need to determine the English abbreviation of a language as locale, such as en-US. This locale value should strictly refer to the Chromium Source Code.
The internationalization of Motrix Next uses vue-i18n.
The configuration files are divided by locale under src/shared/locales/, such as src/shared/locales/en-US and src/shared/locales/zh-CN.
There are language files in each directory organized by business module:
about.jsapp.jsedit.jshelp.jsindex.jsmenu.jspreferences.jssubnav.jstask.jswindow.js
- Create a new directory under
src/shared/locales/with the locale code (e.g.src/shared/locales/de/) - Copy the files from
src/shared/locales/en-US/as a template - Translate each file
- Register the locale in
src/shared/locales/all.js - Submit a Pull Request
Use Conventional Commits:
feat: add torrent file selection
fix: handle empty bitfield in peer parser
refactor: extract TorrentUpload sub-component
test: add rename utility tests
docs: update CONTRIBUTING guidelines
Hard limits — PRs that exceed these will be closed without review:
- < 300 lines of changed code (excluding tests and auto-generated files like
Cargo.lock). - < 10 files touched. Docs-only or config-only PRs may exceed this.
- One concern per PR. A single PR should do exactly one thing.
How to split a large change:
| Instead of | Split into |
|---|---|
| "Add error notification system" (1000 LOC) | PR 1: errorNormalizer.ts + tests → PR 2: useAppNotification.ts + tests → PR 3: integrate into components |
| "Add feature + fix lint + update config" | PR 1: lint/config fixes → PR 2: the feature |
| "Update i18n for 3 features" | One PR per feature, each updating all 26 locales |
- Bug fixes — open an issue first to confirm the bug, then reference it in the PR.
- New features — open an issue and get maintainer approval before writing code. PRs for undiscussed features will be closed. This is standard practice across the Tauri ecosystem.
- Refactors — keep them purely behavioral-neutral. Don't sneak functional changes into a refactor PR.
PR titles must follow Conventional Commits format:
feat(macos): add native traffic light toggle
fix: handle null errorCode in task notification
refactor: extract tracker sync into composable
docs: update i18n translation guide
Run the full check suite locally. PRs that fail any of these will not be reviewed:
pnpm format:check # Prettier formatting
npx vue-tsc --noEmit # TypeScript strict mode
pnpm test # Vitest unit tests
cd src-tauri && cargo test # Rust tests
cd src-tauri && cargo clippy # Rust lints (zero warnings)If you add or modify i18n keys, all 26 locales must be updated using a batch Python script. Partial updates (e.g., only en-US and zh-CN) break the app for other languages and will not be accepted. See AGENTS.md Section D for the script template and the full list of locale directories.
Using AI tools (Copilot, Claude, ChatGPT, Cursor, etc.) to assist development is welcome and encouraged. What is not acceptable is blind vibe coding — generating code with AI and submitting it without understanding or reviewing it.
Rules:
- You must review and understand every line you submit, whether you wrote it or an AI did.
- You must be able to explain any change if asked during review.
- Tests must be written before implementation (TDD), not bolted on after.
- All checks must pass locally before pushing — not after a chain of fix commits.
Disclosure:
The PR template includes an AI usage disclosure section. Fill it out honestly. Following the OpenInfra Foundation standard, you may also add a commit trailer:
feat: add speed limit control
AI-Assisted-By: Claude
What gets your PR closed immediately:
- Commit history showing a "generate → push → fix → fix → fix" loop.
- Code that doesn't pass lint, type checks, or tests on first push.
- Misleading AI disclosure (claiming no AI was used when it was).
This policy follows practices adopted by Mozilla.ai, Drupal, and Ghostty, among others.
By contributing, you agree that your contributions will be licensed under the MIT License.