A fast, compact TUI for directory navigation and bookmark management.
bmrk is a compact inline TUI that fits in 8 rows and never takes over your terminal screen. Navigate directories, manage bookmarks, search for folders and files — all from the keyboard.
The binary is bmrk. The shell wrapper bm wraps it and handles cd automatically — because a
process cannot change its parent shell's directory, a thin wrapper is required (the same approach
used by fzf, zoxide, and autojump).
- Compact inline mode — 8 rows, no fullscreen takeover, terminal fully restored on exit
-
Bookmarks — save and jump to favorite directories;
bm myprojectnavigates instantly - Interactive tree view — directory navigation with expand/collapse
- Fuzzy search — fast asynchronous search with intelligent matching
-
Disk selection — browse and switch between all drives/mount points (
dkey) - Mouse support — click, double-click, scroll
- Customizable — TOML configuration with theme presets and custom colors
From crates.io:
cargo install bmrkFrom source:
git clone https://github.com/holgertkey/bmrk.git
cd bmrk
cargo build --releaseThe binary is at target/release/bmrk (Linux/macOS) or target\release\bmrk.exe (Windows).
The repository includes three ready-made wrapper files. Each one integrates bmrk with a specific
shell so that cd works correctly. Pick the file that matches your environment.
What it does. bm.bat is a batch script that runs bmrk.exe and redirects its stdout to a
temporary file. If the captured output is a valid directory path, it calls cd /d to change the
current session's directory. Non-directory output (help text, version, bookmark lists) is printed
as-is. The previous directory is saved in %BMRK_PREV_DIR% so that bm - can return to it.
Flags that do not trigger navigation (-h, --help, -v, --version, -l, --list, -a,
--add, -c, -d, --del) are passed straight through to bmrk.exe.
Installation:
-
Copy
bmrk.exeandbm.batto the same directory that is on yourPATH(e.g.C:\Users\<YourName>\bin\). -
If that directory is not on your PATH yet, add it and open a new CMD window:
setx PATH "%PATH%;C:\Users\<YourName>\bin" -
Test:
bm --version bm
What it does. bm.ps1 defines a bm function for PowerShell. It runs bmrk.exe, captures
stdout to a temporary file, and calls Set-Location if the result is a valid directory path.
The previous directory is stored in $env:BMRK_PREV_DIR for bm - support. Pass-through flags
(-h, --help, -v, --version, -l, --list, -a, --add, -c, -d, --del) are forwarded
directly to bmrk.exe without any cd logic. Compatible with Windows PowerShell 5.1 and
PowerShell 7+.
Installation:
-
Copy
bmrk.exeto a directory on your PATH (e.g.C:\Users\<YourName>\bin\). -
Open your PowerShell profile for editing:
notepad $PROFILEIf the file does not exist yet, create it first:
New-Item -ItemType File -Force $PROFILE
-
Add the following line to your profile:
. "C:\path\to\bmrk\bm.ps1"
-
Reload the profile:
. $PROFILE
-
Test:
bm --version bm
What it does. bm.sh defines a bm function for POSIX-compatible shells (bash and zsh). It
runs bmrk via command substitution, captures stdout, and calls cd when the result is a valid
directory. The previous directory is stored in $BMRK_PREV_DIR for bm - support. Any output
that is not a directory path (help text, version, bookmark list) is echoed to the terminal
unchanged. For fish, use bm.fish instead (see below).
Installation — bash:
-
Copy the
bmrkbinary to a directory on your PATH:cp target/release/bmrk ~/.local/bin/ # or: sudo cp target/release/bmrk /usr/local/bin/
-
Source the wrapper from your shell config:
echo 'source /path/to/bmrk/bm.sh' >> ~/.bashrc
-
Reload and test:
source ~/.bashrc bm --version bm
Installation — zsh:
Same steps as bash, but add to ~/.zshrc instead of ~/.bashrc.
What it does. bm.fish defines a bm function for fish. Fish uses its own function-file
format and cannot source bm.sh directly, so this is a separate file. It runs bmrk, captures
stdout, and calls cd when the result is a valid directory. The previous directory is stored in
$BMRK_PREV_DIR for bm - support. Any output that is not a directory path (help text, version,
bookmark list) is echoed to the terminal unchanged.
Installation:
-
Copy the
bmrkbinary to a directory on your PATH:cp target/release/bmrk ~/.local/bin/ # or: sudo cp target/release/bmrk /usr/local/bin/
-
Copy or symlink
bm.fishinto fish's functions directory:cp /path/to/bmrk/bm.fish ~/.config/fish/functions/bm.fish # or, to keep it in sync with the repo: ln -s /path/to/bmrk/bm.fish ~/.config/fish/functions/bm.fish
-
Fish picks up functions in that directory automatically — no reload step needed. Test with:
bm --version bm
bm # Open interactive TUI (compact, 8 rows)
bm /path/to/dir # Open TUI at specific directory
bm myproject # Jump to bookmark (cd directly, no TUI)
bm myproject/src/app # Jump into a sub-directory of a bookmark
bm - # Return to previous directory
# Bookmark management
bm -l # List all bookmarks
bm -a work # Save current directory as 'work'
bm -a work /some/path # Save specific path as 'work'
bm -d work # Remove bookmark 'work'
bm -v / --version # Print version
bm -h / --help # Print help| Key | Action |
|---|---|
j / ↓
|
Move down |
k / ↑
|
Move up |
l / →
|
Expand directory |
h / ←
|
Collapse directory; go to parent once collapsed (from the root row, always goes to parent) |
u |
Go to parent directory |
Backspace |
Go back (undo last navigation) |
Enter |
Go into directory (change root) |
q |
Exit and cd to selected dir |
Esc |
Exit without cd |
/ |
Search |
Tab |
Quick jump (type a folder name to jump to it) |
m |
Create bookmark |
' |
Select bookmark |
d |
Disk selection |
c |
Copy selected item's path to clipboard |
Config file is created automatically on first run:
-
Linux/macOS:
~/.config/bmrk/config.toml -
Windows:
%APPDATA%\bmrk\config.toml
Bookmarks are stored as bookmarks.json in the same directory. A background-built directory
index cache lives alongside them as dir_index.txt — it's a performance optimization, not user
data, so it's safe to delete to force a rebuild.
[appearance]
theme = "default" # default, gruvbox, nord, tokyonight, dracula, obsidian
max_name_length = 80 # Truncate long names in the middle (0 = disabled)
icons = "unicode" # "unicode" (▼▶) or "ascii" (v>)
show_cursor_path = true # Show the selected item's full path in the header (Tab mode too)
[appearance.colors]
# header_path_color = "cyan" # Path/label in the header row
# header_hints_color = "darkgray" # Key hints in the header row
# directory_color = "gray" # Directory names; also the header icon (▼)
# See docs/configuration.md for all available color fields
[behavior]
show_hidden = true
follow_symlinks = true
mouse_scroll_lines = 1
[keybindings]
search = ["/"]
create_bookmark = ["m"]
select_bookmark = ["'"]
select_disk = ["d"]
go_to_parent = ["u"]
copy_path = ["c"]
go_back = ["Backspace"]
quit = ["q"]
exit = ["Esc"]
[index]
enabled = true # Background directory index accelerating Tab/`/` under `roots`
refresh_hours = 24 # Rebuild once the cached index is older than this
# roots = ["/home/username"] # Defaults to the home directory
# ignore_dirs = ["node_modules", "target", ".git"] # Replaces the default skip-list, not mergedbmrk writes its TUI to stderr (visible in the terminal) and the selected directory path to
stdout. The wrapper captures stdout via a temp file (CMD: set /p; PowerShell/bash: $t):
- If captured output is a valid directory path →
cdto it (saves previous dir forbm -) - If output is empty (Esc pressed) → do nothing
- Otherwise → print the output as-is (help, version, bookmark list)
| Command | bmrk stdout | Wrapper action |
|---|---|---|
bm (TUI → q) |
/selected/path |
cd there |
bm myproject |
/bookmarked/path |
cd there |
bm myproject/sub |
/bookmarked/path/sub |
cd there |
bm - |
(no bmrk call) |
cd to previous dir |
bm -l |
Bookmarks: … (text) |
Print it (passthrough) |
bm -a work |
Bookmark 'work' added: … |
Print it (passthrough) |
bm -d work |
Bookmark 'work' removed |
Print it (passthrough) |
bm --help |
Help text | Print it (passthrough) |
bm -v |
Version + build info | Print it (passthrough) |
bm (TUI → Esc) |
(empty) | Do nothing |
MIT — see LICENSE.
See CHANGELOG.md for version history.
