skim
Rust-based fzf alternative with async support.
Official WebsiteFeatures
Installation
brew install skpacman -S skimcargo install skimWhy Use skim?
skim (sk) is a fast fuzzy finder written in Rust. It maintains high compatibility with fzf while providing Rust's performance and safety benefits.
Rust-Based
Combines memory safety with high performance. Less prone to crashes, ensuring stable operation.
Async Processing
Parallel processing of input reading and search. Displays results immediately even with large datasets.
fzf Compatible
Supports almost the same options and syntax as fzf. Existing fzf configurations migrate seamlessly.
Unique Features
Includes regex search, interactive mode, and multi-select preview among other unique features.
Installation
# macOS (Homebrew)
brew install sk
# Ubuntu/Debian (Download binary)
# Download the latest version from https://github.com/lotabout/skim/releases
# Arch Linux
sudo pacman -S skim
# Install with Cargo (Rust) (Recommended)
cargo install skim
# Install shell integration
# For Homebrew
$(brew --prefix)/opt/sk/share/skim/install
# For Cargo
~/.cargo/bin/sk-share/installBasic Usage
Basic Commands
# Search for files in current directory and subdirectories
sk
# Combine with find
find . -type f | sk
# Open selected file in editor
vim $(sk)
# Multiple selection (-m option)
sk -m
# Use sk instead of fzf (compatibility)
# Commands from fzf work as-is
history | sk
git branch | sk | xargs git checkoutPipeline Usage Examples
# Search command history
history | sk
# Kill a process
ps aux | sk | awk '{print $2}' | xargs kill
# Switch git branch
git branch | sk | xargs git checkout
# Select commit from git log
git log --oneline | sk | awk '{print $1}'
# Search environment variables
env | sk
# Select docker container
docker ps | sk | awk '{print $1}'
# Full text search with ripgrep
rg --color=always --line-number "" | sk --ansiskim Output Example
The "async" indicator is a key feature. Search results display in real-time even while data is loading.
Shell Integration
skim provides the same shell integration features as fzf. They become active when you run the install script.
| Key Binding | Function | Description |
|---|---|---|
| Ctrl+R | History Search | Fuzzy search command history and execute |
| Ctrl+T | File Search | Search for files and insert into command line |
| Alt+C | Directory Navigation | Search for directory and cd into it |
# Add to ~/.bashrc or ~/.zshrc
# Enable skim shell integration
[ -f ~/.skim/shell/key-bindings.bash ] && source ~/.skim/shell/key-bindings.bash # bash
[ -f ~/.skim/shell/key-bindings.zsh ] && source ~/.skim/shell/key-bindings.zsh # zsh
# For Homebrew
[ -f $(brew --prefix)/opt/sk/share/skim/key-bindings.bash ] && source $(brew --prefix)/opt/sk/share/skim/key-bindings.bash
[ -f $(brew --prefix)/opt/sk/share/skim/key-bindings.zsh ] && source $(brew --prefix)/opt/sk/share/skim/key-bindings.zsh
# Also enable completion
[ -f ~/.skim/shell/completion.bash ] && source ~/.skim/shell/completion.bash # bash
[ -f ~/.skim/shell/completion.zsh ] && source ~/.skim/shell/completion.zsh # zshUseful Aliases
# Add to ~/.bashrc or ~/.zshrc
# For migration from fzf (use sk as fzf)
alias fzf='sk'
# Search files with preview
alias skp='sk --preview "bat --color=always --style=numbers --line-range=:500 {}"'
# Switch git branch
alias gb='git branch | sk | xargs git checkout'
# Interactive git add
alias ga='git status -s | sk -m | awk "{print \$2}" | xargs git add'
# Kill process
alias skill='ps aux | sk | awk "{print \$2}" | xargs kill -9'
# Change directory
alias skcd='cd $(find . -type d | sk)'
# Open recently edited file
alias ske='vim $(sk)'
# Interactive full text search with ripgrep + skim
alias rsk='sk --ansi -i -c "rg --color=always --line-number "{}"" --preview "bat --color=always {1} --highlight-line {2}" --preview-window "+{2}-10"'
# Enter docker container via exec
alias dexec='docker exec -it $(docker ps | sk | awk "{print \$1}") /bin/bash'Vim/Neovim Integration
Using the skim.vim plugin enables skim functionality within Vim/Neovim. It provides an interface nearly identical to fzf.vim.
Installation
" Using vim-plug
Plug 'lotabout/skim', { 'dir': '~/.skim', 'do': './install' }
Plug 'lotabout/skim.vim'
" Using packer.nvim (Neovim)
use { 'lotabout/skim', run = './install' }
use { 'lotabout/skim.vim' }
" Using lazy.nvim (Neovim)
{ 'lotabout/skim', build = './install' },
{ 'lotabout/skim.vim' },Main Commands
| Command | Function |
|---|---|
:SK | Basic file search |
:Files | File search (within project) |
:GFiles | Search files tracked by Git |
:Buffers | Search open buffers |
:Rg | Full text search with ripgrep |
:Lines | Search lines in all buffers |
:History | Search file history |
Key Mapping Examples
" ~/.vimrc or init.vim
" File search
nnoremap <C-p> :Files<CR>
nnoremap <leader>f :Files<CR>
" Git file search
nnoremap <leader>g :GFiles<CR>
" Buffer search
nnoremap <leader>b :Buffers<CR>
" Full text search (ripgrep)
nnoremap <leader>r :Rg<CR>
" Line search
nnoremap <leader>l :Lines<CR>
" Command history
nnoremap <leader>h :History:<CR>skim Key Bindings
| Key | Action |
|---|---|
| Ctrl+J / Ctrl+N | Move to next item |
| Ctrl+K / Ctrl+P | Move to previous item |
| Enter | Confirm selection |
| Tab | Multiple selection (with -m option) |
| Ctrl+A | Select all (with -m option) |
| Ctrl+C / Esc | Cancel |
| Ctrl+U | Clear input |
| Ctrl+/ | Toggle regex mode |
skim Unique Features
Interactive Mode (-i)
Re-executes commands each time the search query changes. Enables powerful full-text search when combined with ripgrep.
# Run ripgrep interactively
sk --ansi -i -c 'rg --color=always --line-number "{}"'
# More practical example (with preview)
sk --ansi -i -c 'rg --color=always --line-number "{}"' \
--preview 'bat --color=always --highlight-line {2} {1}' \
--preview-window '+{2}-10'Regex Search
# Search in regex mode
sk --regex
# Toggle regex mode with Ctrl+/ after launching
# Regex examples
# ^src for files starting with src
# \.rs$ for files ending with .rs
# test.*spec for files containing both test and specField Delimiter
# Limit search to specific fields only
# Specify field delimiter with -n
echo -e "1:foo:bar\n2:baz:qux" | sk -d ':' --nth 2
# Search git log excluding date
git log --oneline | sk --nth 2..
# Search only filename from ripgrep results
rg --line-number "" | sk -d ':' --nth 1Environment Variables
# Add to ~/.bashrc or ~/.zshrc
# Default options (can also use same variable names as fzf)
export SKIM_DEFAULT_OPTIONS='
--height=40%
--layout=reverse
--border
--preview-window=right:50%
--bind=ctrl-d:preview-page-down
--bind=ctrl-u:preview-page-up
--color=fg:#c0caf5,bg:#1a1b26,hl:#bb9af7
--color=fg+:#c0caf5,bg+:#292e42,hl+:#7dcfff
--color=info:#7aa2f7,prompt:#7dcfff,pointer:#7dcfff
--color=marker:#9ece6a,spinner:#9ece6a,header:#9ece6a
'
# Default command (using fd)
export SKIM_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
# For Ctrl+T
export SKIM_CTRL_T_COMMAND="$SKIM_DEFAULT_COMMAND"
export SKIM_CTRL_T_OPTS="--preview 'bat --color=always --line-range :500 {}'"
# For Alt+C
export SKIM_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'
export SKIM_ALT_C_OPTS="--preview 'eza --tree --color=always {} | head -200'"Migration from fzf
skim has high compatibility with fzf, so in most cases you can migrate by just changing the command name.
| fzf | skim | Compatibility |
|---|---|---|
fzf | sk | Fully compatible |
FZF_DEFAULT_COMMAND | SKIM_DEFAULT_COMMAND | Fully compatible |
FZF_DEFAULT_OPTS | SKIM_DEFAULT_OPTIONS | Mostly compatible |
--preview | --preview | Fully compatible |
--bind | --bind | Fully compatible |
| fzf.vim | skim.vim | Mostly compatible |
# Use fzf config as-is with skim (alias setup)
alias fzf='sk'
# Make environment variables compatible
export SKIM_DEFAULT_COMMAND="$FZF_DEFAULT_COMMAND"
export SKIM_DEFAULT_OPTIONS="$FZF_DEFAULT_OPTS"
# Replace shell integration
# Load skim instead of fzf in .bashrc / .zshrcComparison with fzf
| Feature | skim | fzf |
|---|---|---|
| Language | Rust | Go |
| Async Processing | Native support | Limited |
| Regex Search | Built-in support | Depends on external tools |
| Interactive Mode | -i option | Achieved with --bind |
| Community | Growing | Large |
| Plugins/Integration | Good | Extremely abundant |
| Memory Usage | Efficient | Standard |
Tips
- •The
-ioption (interactive mode) is skim's greatest feature. Full-text search combined with ripgrep is extremely powerful - •fzf users can simply set
alias fzf=skand continue using existing workflows as-is - •Toggle between regex mode and fuzzy mode with
Ctrl+/ - •Async processing ensures the UI never blocks, even with massive file counts
- •Being Rust-based means fewer crashes from segmentation faults and more stability
- •Combining
--nthand-dallows you to search only specific fields