This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
BetterMediaInfo is a cross-platform desktop application that provides a modern GUI for MediaInfo. It's built using:
- Frontend: React 19 + TypeScript with Material-UI (MUI) v7
- Backend: Rust with Tauri v2 framework
- Native Library: MediaInfoLib (C++) for media file analysis via FFI
- State Management: Zustand for React state
- Package Manager: pnpm for Node.js dependencies
This project requires external MediaInfoLib dependencies to be built first. See docs/development.md for complete setup instructions including:
- Building MediaInfoLib, ZenLib, and zlib from source
- Platform-specific dependencies (Ubuntu packages, Xcode, Visual Studio)
# Install dependencies
pnpm install
# Development mode (hot reload)
pnpm dev
# Alternative: pnpm tauri dev
# Build for production
pnpm build
# Alternative: pnpm tauri build
# Type checking
tsc -b
# Preview production build
pnpm preview
# Run Rust tests
cd src-tauri && cargo test
# Build NSIS installer (Windows)
node src-tauri/scripts/copy_dlls.cjs
node src-tauri/scripts/patch_tauri_conf.cjs- Uses Tauri's bundler which creates platform-specific packages (deb, rpm, AppImage, dmg, exe)
- Vite-based build system with React plugin
- Cross-platform build via GitHub Actions for Linux, macOS, and Windows
- Frontend dev server runs on http://localhost:1420
The application uses a strict protocol-based communication pattern between TypeScript and Rust:
-
Protocol Files:
src/lib/protocol.ts↔src-tauri/src/protocol.rs- Data structures must be kept in sync between TypeScript and Rust
- TypeScript uses interfaces/enums, Rust uses structs/enums with serde serialization
- Field names use camelCase in TypeScript, snake_case in Rust with
#[serde(rename)]
-
IPC Layer:
src/lib/service.ts↔src-tauri/src/lib.rs- TypeScript calls Rust commands via Tauri's
invoke()API - All Tauri commands are defined with
#[tauri::command]attribute - Commands return
Result<T, String>for error handling
- TypeScript calls Rust commands via Tauri's
-
Business Logic: Rust side (
src-tauri/src/controller.rs)- All media file analysis happens in Rust via MediaInfoLib FFI
- File system operations and configuration management in Rust
- Frontend receives processed data structures, never raw FFI data
- React 19: Uses modern React with hooks
- Component Structure (
src/components/):Layout.tsx- Root layout componentMainContent.tsx- Main content area with tab managementToolbar.tsx- Top toolbar with file operationsList.tsx- File list view with card/grid toggle and filtering (uses MUI DataGrid)Details.tsx- Detailed stream property view per fileConfig.tsx- Settings panel with display mode selectionAbout.tsx- About dialog with version infoFooter.tsx- Footer component
- Libraries (
src/lib/):service.ts- Tauri command bindings (invoke layer)store.tsx- Zustand store for global state managementprotocol.ts- TypeScript interfaces matching Rust protocolformat.ts- Data formatting utilities (duration, file size, etc.)dialog.ts- File/directory dialog helpersfs.ts- File system utilities (recursive scanning)types.ts- Additional TypeScript type definitions
- Entry Points:
App.tsx- Root component with MUI theme provider and dark mode logicmain.tsx- React application entry point
main.rs- Application entry point, CLI argument handlinglib.rs- Tauri command handlers (IPC entry points)controller.rs- Business logic layer (file analysis orchestration)media_info.rs- MediaInfoLib FFI bindings and safe wrappersprotocol.rs- Shared data structures with frontendstreams.rs- Media stream parsing and property extractionconfig.rs- Application configuration managementbindings.rs- Auto-generated C bindings (reference only, not used directly)
-
Zustand Store (
src/lib/store.tsx):config- Application configuration (display mode, file extensions, etc.)mediaFiles- List of analyzed media filesmediaDetailedFiles- Files currently open in detail tabsmediaFileToAllPropertiesMap- Map of file paths to all propertiesmediaFileToCommonPropertyMap- Map of file paths to common propertiesmediaFileToStreamCountMap- Map of file paths to stream countsdialogJsonCode- JSON export dialog statedialogNotification- Notification dialog statemediaInfoAbout- MediaInfo version informationmediaInfoParameters- Available MediaInfo parameterstabAboutStatus/tabSettingsStatus- Tab visibility controlviewType- Current view type (Card or Grid)
-
Configuration Persistence:
- Rust side: Config stored as JSON in Tauri's app data directory
- Frontend: Config loaded on startup via
initConfig(), saved on changes - All persistence through Tauri file APIs
The application uses MUI's built-in theming system:
-
Theme Configuration (
src/App.tsx):- Creates MUI theme with
createTheme()based on display mode - Listens to system theme preferences via
window.matchMedia('(prefers-color-scheme: dark)') - Provides theme to entire app via
ThemeProvider
- Creates MUI theme with
-
Display Mode Logic:
- Auto → Uses system preference (light/dark)
- Light → Forces light mode
- Dark → Forces dark mode
- Mode changes trigger theme recreation and re-render
-
Component Styling:
- MUI components automatically use theme colors
- Custom styling via MUI's
sxprop andstyledcomponents - Theme customization includes default component sizes (small buttons, compact tables, etc.)
- Material-UI (MUI) v7: Primary component library
@mui/material- Core components (Button, TextField, Dialog, etc.)@mui/x-data-grid- Advanced data grid for file list view@mui/icons-material- Material Design icons
- Monaco Editor: Code editor for JSON export view (
@monaco-editor/react) - Emotion: CSS-in-JS styling library (used by MUI)
- Rust unit tests:
cd src-tauri && cargo test- Use
cargo test -rfor release mode tests - Use
cargo test [TESTNAME]to run specific tests
- Use
- No JavaScript/TypeScript test framework currently configured
- CI/CD runs cargo tests as part of build validation
External libraries that must be built before BetterMediaInfo:
- zlib v1.3.1: Compression library (static build required)
- ZenLib: MediaArea utility library
- MediaInfoLib v26.01: Core media analysis library
The build process expects these libraries to be in sibling directories:
parent-directory/
├── BetterMediaInfo/
├── MediaInfoLib/
├── ZenLib/
└── zlib/
-
Protocol Synchronization: When adding/modifying data structures, update BOTH
src/lib/protocol.tsANDsrc-tauri/src/protocol.rs. Field names must use camelCase in TypeScript and snake_case in Rust with#[serde(rename)]attributes. -
Tauri IPC: All backend calls must go through
src/lib/service.tsinvoke functions, never call Tauri APIs directly from components. -
MediaInfoLib FFI: The auto-generated
bindings.rsis broken and for reference only. Use the safe wrappers inmedia_info.rs. -
State Management: Use Zustand store from
src/lib/store.tsxfor global state. Component-local state should use React hooks (useState,useMemo, etc.). -
MUI Theme: Always use theme values via
sxprop orstyledAPI instead of hardcoded colors to ensure dark mode compatibility.