Best Practices for Developing with the Motrix Codebase: A Complete Guide

To develop efficiently with the Motrix codebase, always route window creation through the centralized WindowManager class, isolate business logic within the src/core/ directory, enforce renderer URL policies for IPC security, and extend functionality via the sandboxed QuickJS plugin system using the MDXP protocol bridge.

Motrix is a full-featured download manager built on Electron that cleanly separates concerns across main, renderer, and server processes. Whether you are contributing to the agalwood/Motrix repository or building plugins for the ecosystem, understanding these architectural boundaries is essential for writing secure, maintainable code.

Understanding the Multi-Process Architecture

Motrix follows Electron's multi-process model with strict separation between native window management, UI rendering, and download engine logic.

Main Process and Window Management

The main process handles all native OS interactions and window lifecycle events. According to the source code, you must never instantiate BrowserWindow directly; instead, use the centralized WindowManager class.

Renderer Process and Localization

The renderer process contains the React-based UI and must remain sandboxed from Node.js APIs.

Server and Core Logic

All download engine functionality lives outside the Electron main process, enabling Docker-ready headless deployment.

Secure Development Guidelines

Security in Motrix relies on strict validation at process boundaries.

Extending Functionality via the Plugin System

Motrix supports sandboxed plugins running in a QuickJS environment without Node.js access.

MDXP Protocol and Aria2 Wrapper

Plugin Sandboxing

Plugins run in isolated QuickJS contexts. Declare required capabilities in motrix-plugin.json; Motrix will prompt users before granting them. Use the official motrix-plugin scaffolder (pnpm create motrix-plugin) to ensure manifests conform to the SDK specifications.

Development Workflow and Testing

Efficient development requires understanding the build pipeline and testing hierarchy.

Environment Setup


# Install prerequisites (Node ≥22, pnpm)

curl -fsSL https://get.pnpm.io/install.sh | sh
pnpm install

Running and Debugging


# Development mode with hot-reloading for main and renderer processes

pnpm dev

# Unit tests with Vitest

pnpm test

# Integration and E2E tests with Playwright

pnpm test:e2e

Code Quality


# Linting and formatting

pnpm lint

# Type checking without emission

pnpm typecheck

Best practice: Write unit tests against core modules (e.g., src/core/tracker/tracker-manager.test.ts) before exposing new HTTP endpoints. Keep the CI pipeline fast by running only affected tests locally via pnpm test:watch.

Practical Implementation Examples

Adding a New Window Type

// src/main/window/custom-window.ts
import { WindowManager } from './window-manager';
import { WINDOW_CONFIGS } from './window-configs';

export function createStatsWindow(manager: WindowManager) {
  // Register configuration in src/main/window/window-configs.ts first
  manager.open('stats', { show: true });
}

Always register new window configurations in WINDOW_CONFIGS before calling manager.open().

Extending the MDXP Bridge

// src/shared/protocol/commands.ts
export const Commands = {
  ...ExistingCommands,
  GetServerHealth: 'getServerHealth',
};
// src/server/http/app.ts
router.post('/rpc', async (req, res) => {
  const { method, params } = req.body;
  if (method === Commands.GetServerHealth) {
    const health = await getServerHealth(); // core function from src/core/
    return res.json({ result: health });
  }
  // Fallback to existing bridge handler
});

Implementing a Simple Plugin

// my-plugin/src/index.ts
import { definePlugin } from '@motrix/plugin-api';

export default definePlugin({
  id: 'hello-world',
  version: '0.1.0',
  manifest: {
    name: 'Hello World',
    capabilities: ['readNetwork'],
    activationEvents: ['onAddTask'],
  },
  async onAddTask(context) {
    console.log('New task added:', context.task);
    // Modify task before processing
    context.task.url = context.task.url.replace('http://', 'https://');
  },
});

Summary

Frequently Asked Questions

How do I add a new window type to Motrix?

Register the window configuration in src/main/window/window-configs.ts, then obtain an instance via WindowManager.open('yourWindowId') in [src/main/window/window-manager.ts](https://github.com/agalwood/Motrix/blob/main/src/main/window/window-manager.ts). Never instantiate BrowserWindow directly to ensure proper lifecycle management and security policy enforcement.

What is the correct way to add a new RPC command?

Add the command string to src/shared/protocol/commands.ts, then implement the handler in [src/server/http/app.ts](https://github.com/agalwood/Motrix/blob/main/src/server/http/app.ts). Delegate to functions in src/core/ for business logic rather than implementing logic directly in the HTTP layer.

Can I access Node.js APIs from a Motrix plugin?

No. Plugins run in a sandboxed QuickJS environment with no Node.js APIs available. You must declare required capabilities in motrix-plugin.json and interact with the system through the MDXP bridge defined in [src/shared/protocol/bridge.ts](https://github.com/agalwood/Motrix/blob/main/src/shared/protocol/bridge.ts) and the type definitions in [src/shared/types/plugin.ts](https://github.com/agalwood/Motrix/blob/main/src/shared/types/plugin.ts).

How does Motrix handle tracker management?

Tracker health checks and updates are coordinated by [src/core/tracker/tracker-manager.ts](https://github.com/agalwood/Motrix/blob/main/src/core/tracker/tracker-manager.ts). This module runs in the server process, separate from the Electron main process, and persists state via the SQLite-backed task persistence layer.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →