Features · Screenshots · Getting Started · Architecture · Archive Support · Roadmap
⚠️ Under active development. APIs and UI may change without notice.
MiMiNavigator is a dual-panel file manager inspired by Total Commander and Norton Commander, reimagined with native macOS technologies. It combines the efficiency of classic two-panel navigation with modern SwiftUI, Swift concurrency (actors, async/await), and macOS 26 liquid-glass design language.
Why another file manager?
- Finder lacks dual-panel workflow → MiMiNavigator gives you two panels side by side
- Total Commander doesn't exist on macOS → MiMiNavigator brings TC-style menus and hotkeys
- Built as a SwiftUI showcase → clean architecture, strict concurrency, modular packages
![]() |
| Preview |
![]() |
| History |
![]() |
| History |
![]() |
| History |
| Feature | Description |
|---|---|
| Dual Panels | Two independent file panels with synchronized operations |
| Tabbed Interface | Multiple tabs per panel (⌘T open, ⌘W close, ⌘⇧]/[ switch); tab context menu; persistence between launches |
| List & Thumbnail Views | Toggle per panel via toolbar; thumbnail size 16–900 pt via inline status-bar slider |
| Finder-Style Table | Sortable columns: Name, Size, Date, Permissions, Owner, Type |
| Multi-Selection | Cmd+Click toggle, Shift+Click range, Insert mark+next, pattern matching, Ctrl+A |
| Group Operations | Batch Cut/Copy/Compress/Share/Delete on marked files; group context menu |
| Multi-File Drag & Drop | Drag all marked files together; badge preview with count; Finder-compatible; works in both list and thumbnail views |
| Open With | Per-extension LRU (max 5) — recently used apps float to top; "Other..." picks persisted and restored |
| Find Files | Advanced search: by name (wildcards), content, size, date — with archive search |
| Archive VFS | Open archives as virtual directories, navigate inside, auto-repack on exit |
| Parent Directory | ... entry pinned to top of every panel, archive-aware navigation |
| Navigation History | Per-panel history with quick-jump popover |
| Breadcrumb Nav | Click-to-navigate path bar with autocomplete popup (ESC/click-outside dismiss, slide animation) |
| Favorites Sidebar | Quick access to bookmarked locations (FavoritesKit package) |
| Real-time Updates | Automatic refresh on file system changes |
| FTP/SFTP | Remote file browsing via curl (FTP) and Citadel/NIOSSH (SFTP) |
| Network Neighborhood | SMB/AFP share discovery, mounting, and browsing across LAN |
| Connect to Server | Saved server bookmarks with keychain passwords, session reuse, disconnect |
| Key | Action | Key | Action |
|---|---|---|---|
↑ ↓ |
Navigate | Tab |
Switch panels |
Enter |
Open | ⌘R |
Refresh |
F5 |
Copy to other panel | ⌘. |
Toggle hidden files |
⌘O |
Open / Get Info | ⌘T |
New Tab |
⌘W |
Close Tab | ⌘⇧]/⌘⇧[ |
Next/Prev Tab |
Cmd+Click |
Toggle file mark | Shift+Click |
Range select |
Insert |
Toggle mark + next | Ctrl+A |
Mark all files |
Num+ |
Mark by pattern | Num- |
Unmark by pattern |
Num* |
Invert marks | ⌘⌫ |
Delete marked/selected |
Eight menu categories matching Total Commander conventions: Files (F6 Rename, Pack/Unpack, Compare) · Mark (Select/Deselect groups) · Commands (Terminal, CD Tree) · Net (FTP) · Show (View modes, Hidden files) · Configuration · Start (Tabs) · Help.
- macOS 26 Liquid-Glass menu bar with ultra-thin material, gradient borders, and multi-layered shadows
- Pixel-perfect Retina rendering via
backingScaleFactor - Sticky column headers, zebra-striped rows with themed colors (active/inactive panel)
- Zebra background fill extends below file rows to fill empty panel space
- Animated toolbar buttons, NSVisualEffectView popover for autocomplete
- Hidden files shown in bluish-gray, symlinks labeled as "Alias"
MiMiNavigator can browse archives as virtual directories. Double-click opens the archive, .. exits with automatic repacking if files were modified.
50+ formats supported:
| Category | Formats |
|---|---|
| Standard | zip 7z rar tar |
| Compressed TAR | tar.gz tar.bz2 tar.xz tar.zst tar.lz4 tar.lzo tar.lz tar.lzma |
| Packages | deb rpm cab cpio xar |
| macOS | dmg pkg |
| Java/Android | jar war ear aar apk |
| Disk Images | iso img vhd vmdk |
| Legacy | arj lha lzh ace sit sitx Z |
Extraction chain: /usr/bin/unzip → /usr/bin/tar (libarchive) → 7z (fallback). Install 7z for full format support: brew install p7zip.
The app is not notarized. macOS Gatekeeper will block it on first launch. You must run this command after downloading:
xattr -cr ~/Downloads/MiMiNavigator.appThen double-click MiMiNavigator.app as usual.
Alternatively: right-click the app → Open → click Open in the dialog.
Requirements:
- macOS 26+ (Apple Silicon)
- Xcode (latest) with Swift 6.2
- Optional:
brew install swiftlint swift-format p7zip
git clone --recurse-submodules https://github.com/senatov/MiMiNavigator.git
cd MiMiNavigator
zsh Scripts/stamp_version.zsh # sync version from git tag
open MiMiNavigator.xcodeproj
# ⌘R to build and runOr via command line:
zsh Scripts/stamp_version.zsh
xcodebuild -scheme MiMiNavigator -configuration Debug \
-destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO buildProduction Build:
xcodebuild -project MiMiNavigator.xcodeproj -scheme MiMiNavigator \
-configuration Release -derivedDataPath /tmp/mimi_build build CODE_SIGNING_ALLOWED=YESBinary output: /tmp/mimi_build/Build/Products/Release/MiMiNavigator.app
MiMiNavigator/
├── GUI/Sources/
│ ├── App/ # Entry point, AppLogger, toolbar
│ ├── AppDelegates/ # NSApplicationDelegate
│ ├── States/
│ │ ├── AppState/ # AppState (@Observable), SelectionManager,
│ │ │ # MultiSelectionManager, StatePersistence,
│ │ │ # FileListSnapshot, FileSortingService
│ │ ├── Commands/ # AppCommands (menu bindings)
│ │ └── History/ # PanelNavigationHistory, SelectionsHistory,
│ │ # HistoryEntry, FileSnapshot
│ ├── Features/
│ │ ├── Tabs/ # TabItem, TabManager, TabBarView, TabItemView,
│ │ │ # TabContextMenu
│ │ ├── Panels/ # FilePanelView, FileRow, FileRowView,
│ │ │ │ # FileTableRowsView, SelectionStatusBar,
│ │ │ │ # AliasIconComposer, PanelDividerView
│ │ │ ├── FileTable/ # FileTableView (+Actions, +State),
│ │ │ │ # TableHeaderView, TableKeyboardNavigation,
│ │ │ │ # ColumnLayoutModel, ResizableDivider
│ │ │ └── Filter/ # PanelFilterBar, PanelFilterHistory
│ │ ├── Network/ # NetworkNeighborhoodView, NetworkHost,
│ │ │ # NetworkMountService, NetworkDeviceFingerprinter,
│ │ │ # FritzBoxDiscovery, WebUIProber
│ │ └── ConnectToServer/# ConnectToServerView, RemoteFileProvider,
│ │ # RemoteConnectionManager, RemoteServerStore
│ ├── ContextMenu/
│ │ ├── ActionsEnums/ # FileAction, DirectoryAction, MultiSelectionAction,
│ │ │ # PanelBackgroundAction
│ │ ├── Menus/ # FileContextMenu, DirectoryContextMenu,
│ │ │ # MultiSelectionContextMenu, OpenWithSubmenu
│ │ ├── Dialogs/ # ConfirmationDialog, RenameDialog, PackDialog,
│ │ │ │ # BatchConfirmation/Progress, CreateLinkDialog
│ │ │ └── FileConflict/ # FileConflictDialog, ConflictResolution
│ │ └── Services/ # ContextMenuCoordinator, ClipboardManager,
│ │ │ # CompressService, QuickLookService
│ │ ├── Coordinator/ # FileActionsHandler, DirectoryActionsHandler,
│ │ │ # MultiSelectionActionsHandler, ActiveDialog
│ │ └── FileOperations/ # FileOperationsService (core: copy/move/conflict),
│ │ # FileOpsService+Delete, +Rename, +SymLink,
│ │ # BatchOperationCoordinator, DirectorySizeCalculator
│ ├── Services/
│ │ ├── Archive/ # ArchiveManager (actor), ArchiveExtractor,
│ │ │ # ArchiveRepacker, ArchiveFormatDetector,
│ │ │ # ArchiveNavigationState, ArchivePasswordStore
│ │ ├── Scanner/ # DualDirectoryScanner (actor), FileScanner,
│ │ │ # FSEventsDirectoryWatcher
│ │ ├── FileOperations/ # BasicFileOperations, FileDialogs, VSCodeIntegration
│ │ └── Diagnostics/ # SpinnerWatchdog
│ ├── FindFiles/ # FindFilesViewModel, FindFilesCoordinator,
│ │ │ # FindFilesWindowContent, SearchHistoryManager
│ │ └── Engine/ # FindFilesEngine (actor), FindFilesNameMatcher,
│ │ # FindFilesContentSearcher, FindFilesArchiveSearcher,
│ │ # NativeZipReader, FindFilesResultBuffer
│ ├── DragDrop/ # DragDropManager, DragPreviewView,
│ │ # FileTransferConfirmationDialog
│ ├── Menus/ # TC-style glass menu bar, MenuCategory, MenuItem
│ ├── BreadCrumbNav/ # BreadCrumbView, PathAutoCompleteField
│ ├── HotKeys/ # HotKeyStore, HotKeySettingsView, HotKeyRecorderView,
│ │ # ShortcutConflictValidator
│ ├── History/ # HistoryRow, HistoryWindowContent
│ ├── Favorites/ # FavoritesNavigationAdapter, BookmarkStore
│ ├── Settings/ # SettingsWindowView, SettingsColorsPane,
│ │ # DiffToolRegistry, SettingsPermissionsPane
│ ├── SplitLine/ # OrangeSplitView, SplitContainer, DividerAppearance
│ ├── Toolbar/ # ToolbarStore, ToolbarCustomizeView
│ ├── Config/ # DesignTokens, UserPreferences, AppConstants,
│ │ # InterfaceScaleStore, PreferenceKeys
│ └── Localization/ # L10n.swift
├── Packages/ # git submodule → github.com/senatov/MiMiKits (private)
│ ├── ArchiveKit/ # Archive format support module
│ ├── FavoritesKit/ # Reusable favorites module (.dylib)
│ ├── FileModelKit/ # CustomFile model and utilities
│ ├── LogKit/ # Centralized logging (SwiftyBeaver)
│ ├── NetworkKit/ # Network neighborhood discovery (SMB/AFP)
│ └── ScannerKit/ # File scanning utilities
└── GUI/Docs/ # Architecture docs, screenshots
| Pattern | Usage |
|---|---|
@Observable + @MainActor |
AppState — global app state, panels, archive states |
@Observable + @MainActor |
MultiSelectionManager — Cmd/Shift click, Insert mark, pattern match |
@Observable + @MainActor |
TabManager — per-panel tab collection, persistence, navigation |
@Observable + @MainActor |
ContextMenuCoordinator — singleton handling all context menu actions |
actor |
DualDirectoryScanner — thread-safe file scanning |
actor |
ArchiveManager — session lifecycle, dirty tracking, extraction, repacking |
AsyncStream |
FindFilesEngine — streaming search results with cancellation |
filesForOperation() |
Unified API: returns marked files if any, single selected file otherwise |
NSEvent.modifierFlags |
Detecting Cmd/Shift during SwiftUI gesture handlers |
| Security-Scoped Bookmarks | Persistent file access in sandboxed mode |
| Swift Package (dynamic) | FavoritesKit — extracted as reusable .dylib |
Uses SwiftyBeaver with tags: [FindEngine] [ArchiveSearcher] [Extractor] [Repacker] [FormatDetector] [SELECT-FLOW] [NAV] [DOUBLE-CLICK]
Log files:
- Sandboxed:
~/Library/Containers/Senatov.MiMiNavigator/Data/Library/Application Support/MiMiNavigator/Logs/MiMiNavigator.log - External (dev):
/private/tmp/MiMiNavigator.log
- Dual-panel navigation with breadcrumbs
- Finder-style sortable table (Name, Size, Date, Permissions, Owner)
- Drag & drop with HIG confirmation
- TC-style menu system (8 categories)
- macOS 26 liquid-glass UI
- Navigation history per panel
- File copy (F5), Open/Get Info (⌘O)
- Hidden files toggle with persistence
- Security-scoped bookmarks
- FavoritesKit Swift Package
- Archive virtual filesystem (50+ formats)
- Find Files with archive search
- Parent directory navigation (
..) - Multi-selection: Cmd+Click, Shift+Click, Insert, pattern matching, Ctrl+A
- Group context menu with batch operations
- Multi-file drag & drop with badge preview (list and thumbnail modes)
- Batch-aware file actions (Cut/Copy/Delete/Compress/Share on marked files)
- Total Commander style marking: dark red, semibold, enlarged font
- Selection status bar (marked count + total size + disk free space + inline slider)
- Thumbnail grid view per panel (16–900 pt, QL thumbnails, context menu, drag-drop)
- Open With LRU per file extension (max 5, "Other..." picks persisted)
- Column width persistence
- Hotkey customization
- Tabbed interface (multiple tabs per panel, context menu, persistence)
- Archive Open → TC-style virtual directory (not Finder/Archive Utility) NOT READY YET!
- Zebra-striped background fill for empty panel space
- Autocomplete popup: click-outside / ESC dismiss, slide animation, NSVisualEffectView
- FileOperationsService split into modular extensions (Delete, Rename, SymLink)
- HIGAlertDialog extracted to own file
- Firmlink handling for
/tmp,/var,/etcin scanner and file operations - Rename: panel tracking, scan cooldown fix, firmlink path resolution
- Version auto-sync from git tag via
Scripts/stamp_version.zsh
- Batch rename for marked files
- Terminal integration at current path
- Custom themes and color schemes
- Scroll-to-selection after rename/create operations
- Three-panel layout option
- FTP/SFTP connectivity (Citadel SFTP + curl-based FTP)
- Network filesystem (SMB/AFP mount, Network Neighborhood discovery)
- Cloud storage (iCloud, Dropbox)
- Advanced file comparison
- Plugin system
- App Store release
Contributions welcome! MiMiNavigator is a real-world SwiftUI project with clean architecture, strict Swift 6.2 concurrency, and plenty of room to grow.
Looking for a way to start? Here are areas where help is especially appreciated:
| Area | Difficulty | Description |
|---|---|---|
| Batch Rename | ⭐⭐ | Rename multiple marked files with pattern (e.g. Photo_{N}.jpg) |
| File Preview | ⭐⭐ | Quick Look panel for selected file (QLPreviewPanel integration) |
| Themes | ⭐⭐ | Dark/light/custom color schemes with persistence |
| Localization | ⭐ | Translate UI strings (German and Russian already done) |
| Unit Tests | ⭐⭐ | Tests for MultiSelectionManager, FileOperations, ArchiveManager |
| FTP/SFTP | ⭐⭐⭐ | Remote file system panel via Network framework |
| Performance | ⭐⭐ | Profile and optimize for directories with 10k+ files |
- Fork the repo and create a feature branch
- Read CONTRIBUTING.md for code style and commit guidelines
- Build and test locally (
⌘Rin Xcode) - Open a PR with a clear description and screenshots for UI changes
- Learn SwiftUI on a real dual-panel file manager (not a todo app)
- Swift 6.2 concurrency — actors, async/await,
@Observable, strict Sendable - macOS-native development — NSWorkspace, security-scoped bookmarks, Quick Look, AppleScript
- Clean architecture — modular structure, no file over 400 lines, extensive logging
- Friendly maintainer who reviews PRs quickly
I openly acknowledge using AI assistants for architecture discussions and code review. This README was crafted with care for both humans and crawlers.
MiMiNavigator uses the following open-source libraries. We are grateful to their authors.
- Author: Sebastian Kreutzberger and contributors
- License: MIT
- Repository: https://github.com/SwiftyBeaver/SwiftyBeaver
- Usage in project: All application logging -- console output and persistent log file at
~/Library/Logs/MiMiNavigator.log. Bootstrapped inLogKitpackage, re-exported as globallogacross all source files so every module can uselog.debug / log.info / log.errorwithout additional imports.
- Author: Joannis Orlandos (Orlandos BV) and contributors
- License: MIT
- Repository: https://github.com/orlandos-nl/Citadel
- Usage in project:
SFTPFileProvider-- full SFTP connectivity in the Connect to Server feature. ProvidesSSHClient,SFTPClient, and OpenSSH private-key parsing. Replaces what would otherwise require spawning ssh/sftp CLI processes or linking against libssh2.
Several areas in MiMiNavigator use custom implementations that could be simplified or replaced by existing open-source libraries.
Files: NativeZipReader.swift (~350 lines), ZIP branch of FindFilesArchiveSearcher.swift
Current approach: Custom binary ZIP central-directory parser + Process() wrappers around /usr/bin/unzip, /usr/bin/tar, 7z.
Candidate: ZIPFoundation (MIT, Thomas Zoechling)
- Pure Swift, no
Process()spawning for ZIP/GZIP - Streaming extraction, password-protected archives, in-memory entries
- Would eliminate
NativeZipReaderand its error-prone manual byte-offset arithmetic - TAR/7z/RAR still require CLI fallback (no pure-Swift lib covers all 50+ formats)
File: FTPFileProvider.swift -- parseFTPListing() method
Current approach: URLSession FTP + hand-written Unix-style LIST output parser. Fragile: breaks on IIS FTP, DOS-style listings, localized dates. URLSession FTP is deprecated by Apple.
Candidate: curl via Process() -- already present on every Mac
curl -l ftp://host/pathgives clean filename-per-line output, no parsing neededcurl --ftp-ssladds FTPS for free- Handles MLSD, active/passive mode, AUTH TLS automatically
Files: NetworkDeviceFingerprinter.swift (~200 lines), WebUIProber.swift
Current approach: Custom async TCP port prober via POSIX connect(), checks 20+ ports per host in parallel, classifies device type by open-port combination.
Candidate: nmap (GPLv2) via Process()
- Already used manually during development for Vuduo2 diagnostics -- proven reliable
nmap -sV --open -p <ports> <host>returns service names in machine-parseable format- Would eliminate ~200 lines of custom probing logic
- Caveat: requires
brew install nmap; must remain optional with graceful fallback
Status: Resolved -- Citadel (already a SPM dependency) provides Insecure.RSA.PrivateKey(sshRsa:) and Curve25519.Signing.PrivateKey for OpenSSH private key parsing.
File: FindFilesNameMatcher.swift -- ~30-line wildcard-to-regex converter. Works correctly for current feature set; worth revisiting only if {a,b} alternation or ** recursive matching is needed.
MiMiNavigator is developed by Iakov Senatov -- Diplom-Ingenieur (Chemical Process Engineering), 35 years of programming experience.
Sincere thanks to the open-source community:
| Author | Project | Why it matters |
|---|---|---|
| Sebastian Kreutzberger | SwiftyBeaver | Clean, fast, zero-ceremony logging that just works |
| Joannis Orlandos | Citadel | Excellent SSH/SFTP library, bridges the gap SwiftNIO SSH leaves open |
| Thomas Zoechling | ZIPFoundation | Model of clean Swift API design, earmarked for adoption |
| The nmap Project | nmap | Gold standard in network diagnostics, invaluable during LAN discovery development |
| Apple | SwiftNIO, SwiftUI, kqueue, NetServiceBrowser | Making macOS-native development a genuine pleasure |
Special thanks to Anthropic / Claude for pair-programming throughout this project -- architecture decisions, refactoring, debugging, and documentation.
AGPL-3.0 — Iakov Senatov
Made with ❤️ for macOS · Building the future of file management, one commit at a time



