- React 19 + TypeScript + Vite
- Material UI 9, Emotion, and dnd-kit for drag/reorder UX
- i18next + react-i18next for localization (9 locales)
- Zustand as the single source of truth for files, queue state, metadata, and config
- Tauri JS APIs for commands/events and desktop integrations
- Rust (edition 2024) with Tauri v2
- Native Rust media metadata parser under
src-tauri/src/media_metadata/ - JSON-only wire protocol (
invokecommands + Tauri events) - Tokio runtime for async command handling plus dedicated worker threads for merge processes
tauri-plugin-clipboard-managertauri-plugin-dialogtauri-plugin-opener
- MKVToolNix (
mkvmerge) is required for merge execution - BetterMediaInfo is optional and enabled when configured in Settings
src/: React app (UI, state store, protocol/types, service wrappers)src/components/: UI screens/widgets (cards, queue, settings, toolbar)src/i18n/locales/: locale dictionaries (9 languages)src-tauri/src/: Tauri backend (config, controller, merge queue, protocol)src-tauri/src/media_metadata/: native parser implementationsrc-tauri/tests/: Rust integration tests (including TypeScript protocol regeneration checks)docs/parsers/: parser coverage and behavior notes per formatscripts/ts/: maintenance scripts (including multi-file version bumping)
pnpm install # install JS dependencies
pnpm tauri dev # run the app in development (hot-reload frontend + Rust)
pnpm tauri build # build installers for the current platform
pnpm dev # run only the Vite dev server (no Tauri window)
pnpm build # type-check and build the frontend
cd src-tauri && cargo check # fast Rust type-check
cd src-tauri && cargo test # run Rust unit + integration testsTo bump the version across package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json, and the three workflow files, edit both arguments at the bottom of scripts/ts/change-version.ts and run:
cd scripts/ts
deno task change-versionThe persisted config file is named BatchMkvMerge.json and lives at:
- Windows —
%APPDATA%\BatchMkvMerge\when installed under%LOCALAPPDATA%/%ProgramFiles%/%ProgramFiles(x86)%; next to the.exein portable mode. - Linux —
$XDG_CONFIG_HOME/BatchMkvMerge/, else$HOME/.config/BatchMkvMerge/. - macOS —
~/Library/Application Support/BatchMkvMerge/.
All communication goes through Tauri's invoke and event system; there's no IPC codec beyond JSON.
- App/config/update:
get_aboutget_configset_configget_update_resultskip_versionget_launch_args
- File discovery + metadata:
get_media_filesget_media_metadata
- Merge workflow:
enqueue_mergecancel_mergeget_merge_statusresolve_merge_output_pathresolve_overridden_output_pathcheck_output_path_writableoutput_path_exists
- External tools:
is_mkvtoolnix_founddetect_better_media_infolaunch_better_media_info
merge-finished- Emitted by the backend when a merge worker exits.
- Payload: file path, terminal outcome (
Completed,Cancelled,Failed), optional error. - Frontend listens in
FileList.tsxand finalizes queue status/notifications.
- Merge scheduling is per drive:
- each drive has at most one active
mkvmergeworker, - additional items for that drive are queued FIFO.
- each drive has at most one active
- Different drives can merge in parallel.
- Backend snapshots expose active states (
Waiting,Merging); terminal outcomes are finalized by event handling plus snapshot fallback logic. - Frontend polls
get_merge_statusevery 200 ms for progress updates.
- Profiles include language and naming automation (
reset_und_language,set_track_name,reset_default_track,reset_forced_display). - The automation settings are persisted in config and applied by the frontend track workflow.
Three GitHub Actions workflows build release bundles on push/PR:
linux_build.yml—.deb,.rpm,.AppImagemacos_build.yml—.dmg(x86_64 and arm64 via matrix)windows_build.yml—.msi,.exe(NSIS)
Each installs Node 24, pnpm 11, and the stable Rust toolchain, then runs frontend build + Rust tests before packaging.
Linux additionally enforces parser line coverage (cargo llvm-cov --fail-under-lines 90) for src-tauri/src/media_metadata/.