How to Customize Motrix's Behavior: 6 Methods from UI to Plugins
Motrix provides six distinct customization paths—from the Settings UI to direct JSON editing, CLI flags, and plugin APIs—all validated through Zod schemas and managed by a central SettingsManager singleton.
Motrix is an open-source download manager built by agalwood that offers extensive flexibility through its layered settings architecture. Whether you need to tweak the user interface, adjust download engine parameters, or extend functionality through plugins, you can customize Motrix's behavior through multiple validated entry points. This guide examines the source code implementation to show exactly how each customization layer works.
Understanding Motrix's Layered Settings Architecture
According to the agalwood/Motrix source code, the application's customizability relies on a strict separation between settings definition, runtime access, UI presentation, and IPC communication. This architecture ensures type safety and consistency across the desktop application, headless server, and plugin runtimes.
Settings Schemas with Zod
All user-tunable options are described using Zod schemas located in src/shared/schemas. These schemas provide runtime validation, TypeScript type safety, and default values. The primary schema files include:
app-settings.ts– Defines UI-level options such as theme, language, and startup behaviorengine-settings.ts– Configures download-engine parameters like SQLite path and history limitsproxy-settings.tsandnat-settings.ts– Handle network-specific configurations
Each schema file exports a Zod object that validates data shape before it reaches the core application logic.
The SettingsManager Singleton
The SettingsManager class in src/core/settings/settings-manager.ts serves as the central authority for settings persistence. This singleton loads the user's JSON configuration file, merges it with schema defaults, and exposes three core methods:
get()– Returns the complete settings snapshotupdate(partial)– Validates and persists changes to diskreset()– Restores default values
Both the desktop application and the headless server share this manager, ensuring identical behavior across runtimes.
IPC Communication Layer
Because the renderer process cannot access the file system directly, Motrix exposes settings through its IPC protocol. The main process implements the GetSettings query and UpdateSettings command in src/main/ipc/queries.ts. The preload bridge exposes these capabilities to the frontend via window.motrix.settings, creating a secure boundary between UI code and system resources.
Renderer UI Components
The Settings page renders dynamic cards based on schema fragments. The generic SettingsCard component in src/renderer/routes/settings/cards/settings-card.tsx receives a portion of the schema and automatically generates form controls. This component maps Zod schema types to input elements, ensuring the UI always reflects the current validation rules.
Six Methods to Customize Motrix's Behavior
You can modify Motrix through six distinct interfaces, ranging from user-friendly graphical controls to programmatic APIs.
1. In-App Settings UI
The most accessible method is the native Settings interface. Navigate through categorized cards—such as Speed Limit, Proxy, or NAT—to adjust values. When you modify a field, the UI dispatches an UpdateSettings call through the IPC layer, and the SettingsManager persists the change to disk immediately. This method requires no technical knowledge and validates inputs in real-time against the Zod schemas.
2. Direct JSON File Editing
For advanced users, Motrix stores all settings in a plain JSON file that you can edit when the application is not running. The file location varies by operating system:
- Linux/macOS:
~/.config/Motrix/settings.json - Windows:
%APPDATA%\Motrix\settings.json
When Motrix launches, the SettingsManager loads this file and validates it against the schemas. Invalid values trigger fallbacks to defaults, preventing crashes from malformed JSON.
3. Command-Line Interface Flags
The @motrix/cli package exposes flags that map directly to core settings. For example, to change the download directory programmatically:
motrix --download-dir /my/custom/path
The CLI uses the same SettingsManager internally, so flags merge into the existing JSON configuration file. This approach is ideal for automation scripts and headless deployments.
4. Programmatic Access in the Main Process
Extensions or internal scripts running in the main process can import the manager directly:
import { SettingsManager } from '@core/settings/settings-manager';
const manager = SettingsManager.getInstance();
const current = manager.get(); // Full settings object
await manager.update({ theme: 'dark' }); // Persists change to disk
This method provides full access to the settings API without IPC overhead, suitable for background tasks or custom integrations.
5. Renderer-Side API for UI Extensions
If you are developing a custom UI component or modifying the renderer process, access settings through the preload bridge:
const settings = await window.motrix.settings.get(); // Fetch current snapshot
await window.motrix.settings.update({ notifyOnComplete: false });
This API interacts with the main process via the IPC layer defined in src/main/ipc/queries.ts, maintaining security while allowing frontend customization.
6. Plugin-Based Customization
Plugins extend Motrix by declaring custom settings in their motrix-plugin.json manifest. Define your schema within the settings key:
{
"settings": {
"myPlugin": {
"enableFeatureX": { "type": "boolean", "default": true },
"customPath": { "type": "string", "default": "/tmp" }
}
}
}
At runtime, the plugin sandbox receives a merged settings object containing both core and plugin-specific values. The Settings UI automatically renders cards for these declarations using the same SettingsCard component, without requiring additional frontend code.
Summary
Customizing Motrix's behavior follows a consistent path through validated schemas and centralized management:
- Zod schemas in
src/shared/schemasenforce type safety and defaults for all configuration options - The SettingsManager singleton in
src/core/settings/settings-manager.tshandles persistence and validation throughget(),update(), andreset()methods - IPC queries in
src/main/ipc/queries.tssecurely expose settings to the renderer process - Six customization methods range from the graphical Settings UI to direct JSON editing, CLI flags, main process APIs, renderer APIs, and dynamic plugin manifests
- All changes flow through the same validation layer, ensuring consistency across desktop, headless, and plugin environments
Frequently Asked Questions
Where are Motrix settings stored on disk?
Motrix persists settings to a JSON file located at ~/.config/Motrix/settings.json on Linux and macOS, or %APPDATA%\Motrix\settings.json on Windows. The SettingsManager loads this file at startup and rewrites it atomically whenever update() is called. You can safely edit this file while the application is closed, and the changes will take effect on the next launch after schema validation.
Can I customize Motrix without opening the GUI?
Yes. You can use the @motrix/cli package to modify settings via command-line flags, or directly edit the settings.json configuration file when the application is not running. Both methods utilize the same SettingsManager and Zod schemas as the graphical interface, ensuring your changes remain valid and persist correctly.
How do plugins add their own settings to Motrix?
Plugins declare custom settings inside their motrix-plugin.json manifest under the settings key, using JSON schema definitions. When the plugin loads, the runtime merges these definitions with core settings and exposes them to the plugin sandbox. The Settings UI automatically renders input controls for these values through the SettingsCard component in src/renderer/routes/settings/cards/settings-card.tsx.
Is it safe to edit the settings.json file manually?
Manual editing is safe if Motrix is not running and you respect the schema definitions in src/shared/schemas. The SettingsManager validates the entire file against Zod schemas at startup, automatically falling back to default values for any invalid entries. However, syntax errors in the JSON itself will prevent the application from parsing the file, so use a JSON validator before saving.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →