A macOS desktop file browser that blends Finder aesthetics with Windows Explorer ergonomics — built for developers who live in the terminal and want a GUI that keeps up.
Built with Electron 32 · React 19 · TypeScript 6 · Zustand 5 · SQLite (better-sqlite3). Renderer fully migrated to React + TypeScript; main process stays vanilla Node for IPC parity. Production bundle: ~694 KB across 24 lazy-loaded chunks.
macOS only.
- Breadcrumb address bar — click any segment to jump; double-click to type a raw path with
~support - Typed-path autocomplete while editing (arrow-key selection)
- Back / Forward / Up / Reload with per-window history stack (⌘← ⌘→ ⌘↑)
- Git root jump (⌘G) — jump to current repo root; ⌘⇧G jumps up one level in monorepos
- Branch + ahead/behind indicator inline in the address bar (
main +3/−1) - Vim-style keys (
j/k/h/l/gg/G) — opt-in via settings - Type-to-navigate: typing in the file list auto-filters and enters single-match folders
- 7-column grid: Name · Date Created · Date Modified · Size · Kind · Permissions · Git status
- Column sort, resize, reorder — persisted per-folder in SQLite
- Folders-before-files sort option; always-on dotfiles; always-show extensions
- Inline filter box; multi-select with Shift + ⌘
- Row density toggle (compact / normal)
- Virtualized rendering for 50k+ entry folders
- Git status column per row (M/A/?/!) with color coding
- Gitignored files dimmed (50% opacity), not hidden — toggle in settings
- Folder size (recursive), computed lazily and cached; "clean size" excludes gitignored files
- Middle-ellipsis truncation preserving file extensions (
MyVeryLongFi…le.tsx) - Full path in row tooltip
- Detects repo root per folder; caches
git status --porcelainwith short TTL - Branch indicator with ahead/behind counts in the address bar
- Per-row git status markers in the file list
- Gitignore-aware file dimming
- Git graph pane (⌘2) — virtualized commit log with SVG rail graph (GitKraken-style lane layout)
- Commit detail view: subject, body, author, parents, per-file
+/− - Staging pane: diff preview, stage/unstage toggles, commit box
- Branch/tag/remote refs in sidebar with checkout via context menu
- Worktree support
- Open (Enter / double-click), Rename (F2), New Folder (⌘⇧N), New File (⌘N)
- Move to Trash (⌘⌫), Reveal in Finder
- Cut / Copy / Paste (⌘X / ⌘C / ⌘V) — interoperable with macOS Finder via
NSPasteboard public.file-url - ⌘⌥V moves instead of copying (matches Finder's "Move Item Here")
- Visual cut state — rows render at 60% opacity until paste
- Bulk rename — regex find/replace, counter tokens (
{name}{ext}{i}{n:NN}{date}{parent}), live preview, collision detection, atomic two-phase apply - Non-blocking copy/move queue with progress, throughput, ETA, pause, cancel
- Conflict resolution: Skip / Replace / Keep Both / Stop, with "Apply to all"
- Undo last file operation (⌘Z), depth ≥ 20
- "Open With" submenu — extension-filtered, system handler discovery via Launch Services, per-extension default app override
- Drag within app between panes / tabs / sidebar (default move; ⌥ copy; ⌃ symlink)
- Drag out to other apps (Finder, Mail, Slack, Cursor, browsers) as file URLs with drag-image
- Drop files in from any macOS app; drop URLs as
.webloc; drop text as auto-named.txt - Spring-loaded folders — hover a folder 800ms while dragging to navigate into it (ESC cancels)
- Visual drop indicator on target rows, tree nodes, and sidebar items
- Split view toggle (⌘D) — two independent panes
- F5 copy to other pane, F6 move to other pane (Midnight Commander keys)
- Folder compare: only-in-A / only-in-B / differs / identical
- Folder sync with preview, dry-run, and apply
- Embedded terminal (F4) via
node-pty+ xterm.js; auto-cdfollows the file list - Shell → file list sync: precmd hook updates the UI when the shell changes directory
- "Open Terminal Here" — configurable for Terminal.app / iTerm / Ghostty / Warp
- Copy Path (⌘⌥C) — single or multi-select, newline-joined
- AI-Copy modes (⌘⌥⇧C cycles): Cursor
@rel/path, Claude Code@path, plain, markdown link - AI-Bundle Copy (⌘⌥⇧V) — concatenate selected file contents with
=== filename ===separators; size-cap warning - Project Context sidebar — auto-detects
CLAUDE.md,AGENTS.md,.cursor/rules/*.mdc,.cursorrules,package.json,pyproject.toml,README.md,.env.example - "Just changed" sidebar — files modified in the last N minutes (default 15), scoped to current repo; "what did Cursor/Claude just touch?"
- "Open in Cursor" action (configurable editor)
- User-defined shell commands in the right-click menu with
$SELECTION,$CWD,$REPO,$NAMEplaceholders - Actions editor in settings (label, command, keybinding, constraints)
- Built-in presets: Open in Cursor, Open in Preview, Open in VS Code, Copy as @-mentions
- Action constraints: requires-selection, requires-single, folder-only, in-git-repo
- Project Context — CLAUDE.md, AGENTS.md, cursor rules, package.json, etc.
- Just Changed — recent files in current repo (configurable window)
- Favorites — pinned folders, drag-to-reorder, seeded with Home / Desktop / Documents / Downloads / Pictures / Music / Movies
- Recent — auto-tracked folders
- Locations — Macintosh HD,
~,/Volumes, eject removable - Tags — user-defined colored tags; multi-tag AND/OR filter
- Details pane (⌘I) — size, mode, owner, group, symlink target, folder count, 4 timestamps; multi-select aggregate
- Permissions editor — clickable
rwxcheckboxes (skips symlinks correctly) - Checksum generation (SHA-256 / MD5 / SHA-1 / SHA-512), streaming, one-click copy
- xattr inspector
- File diff for exactly-2 selections (
cursor --diffor configurable)
- Multiple tabs (⌘T, ⌘W, ⌘⇧T reopen, ⌘⇧[ / ⌘⇧] cycle, ⌘1–⌘9 jump)
- Named sessions — save and restore window / pane / tab layout
- Auto-restore last session on startup
- Inline folder filter (instant)
- Recursive filename search from current folder — streaming, cancelable,
.gitignore-aware, integrated into ⌘P quick-nav
- Command palette (⌘⇧P) — fuzzy-find every menu item and action
- Quick-nav (⌘P) — fuzzy-find tabs, favorites, recents, and cwd
- Item count, selection size, full path
- Mode pills: filter active · terminal open · split · N-cut · drag target
- Git repo signal pill
- cwd hash chip — stable 8-char hash of current path; click to copy full path
Requirements: macOS, Node.js 18+, Xcode Command Line Tools (xcode-select --install)
git clone git@github.com:dlomibao/baoframe.git
cd baoframe
npm install
npm run rebuild # rebuild better-sqlite3 against Electron's ABI
npm startOpen DevTools:
DEV=1 npm startDemo mode (no real filesystem access, fixture data):
npm run demonpm run build:ui # dev bundle with sourcemaps
npm run build:ui:prod # minified production bundle (~694 KB across 24 chunks)
npm run pack # build distributable .app via electron-buildersrc/
├── main/
│ ├── main.js # IPC registration, window lifecycle
│ ├── db.js # SQLite schema + data access (WAL mode)
│ └── services/ # fs, git, search, inspector, xattr, launch-services, pty
├── preload/
│ └── preload.js # contextBridge API (contextIsolation: true, nodeIntegration: false)
└── renderer/ # React 19 + TypeScript 6 + Zustand 5
├── components/ # TSX components
├── hooks/ # shared hooks
├── state/stores/ # Zustand stores + selectors
└── modules/ # vanilla orchestrators (xterm.js, DnD, keybindings, clipboard)
Build pipeline: scripts/build-ui.mjs (esbuild). Heavy surfaces (Inspector, Graph, Terminal, modals, palettes, settings) lazy-load.
SQLite database location:
- macOS:
~/Library/Application Support/baoframe/baoframe.db
Stores: favorites · recents · tags · file_tags · settings · column prefs · folder sizes · named sessions · custom actions
- Multi-tab browsing (UI — IPC layer already supports multiple windows)
- File tagging UI (schema and stores already shipped)
- SQLite FTS5 indexed search with operators (
name:,ext:,size:>1mb,modified:<7d) - Saved searches ("Smart Folders") in sidebar
- Quick Look–style preview pane
- Theme switcher (CSS custom properties in place)
PolyForm Noncommercial 1.0 — free for personal and non-commercial use. Commercial use requires a license — open an issue or reach out.