skim-rs/skim
Fuzzy Finder in rust!
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓9 active contributors
- ✓MIT licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 63% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/skim-rs/skim)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/skim-rs/skim on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: skim-rs/skim
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/skim-rs/skim shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 9 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 63% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live skim-rs/skim
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/skim-rs/skim.
What it runs against: a local clone of skim-rs/skim — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in skim-rs/skim | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of skim-rs/skim. If you don't
# have one yet, run these first:
#
# git clone https://github.com/skim-rs/skim.git
# cd skim
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of skim-rs/skim and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "skim-rs/skim(\\.git)?\\b" \\
&& ok "origin remote is skim-rs/skim" \\
|| miss "origin remote is not skim-rs/skim (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/skim-rs/skim"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Skim is a production Rust fuzzy finder inspired by fzf, providing a single sk executable that filters and searches through files, lines, and commands interactively. It integrates as a CLI tool, Vim/Neovim plugin, and library, with core matching algorithms including Frizbee for advanced pattern scoring and support for ANSI-colored output via the Ratatui TUI framework. Monorepo structure: src/lib.rs exports the core library; src/bin/main.rs wraps it as the sk CLI with clap argument parsing; examples/ contains 15+ runnable demos (base.rs, async.rs, custom_action_keybinding.rs); benches/ has matcher_micro.rs and filter.rs for algorithmic profiling; .github/workflows/ handles CI/CD.
👥Who it's for
Systems engineers, DevOps practitioners, and shell power-users who want a fast, scriptable fuzzy finder for command-line workflows; Rust library developers embedding fuzzy matching in applications; Vim/Neovim users seeking a modern fzf replacement.
🌱Maturity & risk
Skim is actively developed and production-ready: it's at version 4.6.2 with multiple CI workflows (.github/workflows/), comprehensive test coverage via nextest config, and substantial codebase (1M+ Rust LOC). The repo shows consistent maintenance (Cargo.lock is pinned, release automation in place, recent dependency updates in Cargo.toml), though commit recency is not visible in provided data.
Moderate dependencies (~20+ direct, including optional frizbee and gungraun) managed by Cargo with LTO-enabled releases reducing binary size; Rust edition 2024 with MSRV 1.91 may exclude some downstream users. Risk factors: single primary maintainer (Lotabout), complex fuzzy matching logic may harbor edge cases (no mention of formal verification), interprocess IPC via tokio adds complexity.
Active areas of work
Recent activity includes Rust edition 2024 upgrade (Cargo.toml), integration of frizbee matcher as optional feature, profile optimizations (LTO, codegen-units=1), and expansion of examples for library usage patterns (custom_keybinding_actions.rs, downcast.rs). Roadmap visible in CHANGELOG.md and CLAUDE.md suggests ongoing refinement of preview windows and key binding customization.
🚀Get running
git clone https://github.com/skim-rs/skim.git
cd skim
cargo build --release
./target/release/sk
Daily commands:
cargo run --release -- <args>
# or for development with logging:
RUST_LOG=debug cargo run -- --preview 'cat {}'
# run benchmarks:
cargo bench --bench matcher_micro
🗺️Map of the codebase
- src/lib.rs: Main library entry point exposing public API for fuzzy matching, item filtering, and TUI integration; defines Skim, Matcher, Item traits
- src/bin/main.rs: CLI binary entry point; orchestrates clap argument parsing, file input handling, and hands off to library for filtering and display
- ARCHITECTURE.md: Design document explaining internal structure, matching algorithms, preview window IPC, and event loop; essential reading for contributors
- examples/base.rs: Minimal runnable library example; starting point to understand Skim struct initialization, data flow, and result handling without CLI complexity
- Cargo.toml: Feature flags (cli, frizbee, gungraun) define build variants; dependency versions (Ratatui, crossterm, Tokio) are central to architecture
- .github/workflows/test.yml: CI pipeline; shows test matrix (OS, Rust versions), coverage reporting, and validation steps required before merge
- benches/filter.rs: Benchmark suite for matching algorithm; critical for understanding performance characteristics and regression detection
- .config/insta.yaml: Snapshot testing configuration; reveals which tests use insta for output validation (common pattern in TUI projects)
🛠️How to make changes
Core matching logic: src/matcher/ (or matching module in lib.rs) — start with examples/fuzzy_matcher_fz.rs to understand matching API. CLI arguments: src/bin/main.rs delegates to Cargo.toml [features] like cli. TUI rendering: grep for Ratatui Frame usage in src/; ARCHITECTURE.md should detail this. Custom keybindings: examples/custom_keybinding_actions.rs and examples/custom_action_keybinding.rs show patterns; hook into the event loop in src/bin/main.rs. Tests: run with cargo test (nextest config in .config/nextest.toml); add new tests beside implementation files or in tests/ directory.
🪤Traps & gotchas
Preview window IPC: Uses interprocess + Tokio for cross-process preview rendering; requires careful cleanup or zombie processes leak (see src/ for PreviewContext). ANSI color handling: ansi-to-tui 8.0.1 must be kept in sync with Ratatui's Color enum to avoid palette mismatches. Crossterm tty handling: feature flag use-dev-tty required for proper terminal detection in pipes; absence breaks interactive mode. Matcher trait lifetime: fuzzy matchers hold references; lifetime bounds may trap async code if not careful. Rust 1.91 MSRV: Code uses newer syntax (likely 2021 edition features); older Rust won't compile. Shell script integration: bin/sk-tmux is Bash; validate shell compatibility on Darwin vs Linux.
💡Concepts to learn
- Fuzzy Matching (Levenshtein-like scoring) — Core algorithm determining why some matches rank higher; Frizbee and custom matchers implement scoring heuristics (gap penalties, position bonuses) you'll encounter tuning search quality
- Ratatui TUI Framework — Skim's interactive UI is built entirely on Ratatui's widget and rendering system; changes to layout, colors, or key handling require understanding Frame, Rect, and StatefulWidget traits
- Crossterm Event Polling — Skim receives user keypresses via crossterm's event-stream feature with non-blocking async reads; mishandling causes lag or missed inputs in interactive mode
- Tokio Async Runtime & Channels (kanal) — Skim spawns tasks for file I/O, filtering, and preview window IPC; kanal channels coordinate between threads without allocating per-message, critical for low-latency UX
- Interprocess IPC (Unix Sockets / Named Pipes) — Preview window spawned as child process communicates with main skim process via IPC; lifecycle and signal handling require understanding socket cleanup and process trees
- ANSI Escape Sequences & Color Palette Conversion — Input may contain 256-color or truecolor ANSI codes; ansi-to-tui converts them to Ratatui's Color enum; mismatches cause color corruption in output
- Snapshot Testing (insta) — Test suite uses snapshot testing for UI output validation; snapshots commit to repo and require careful review on updates to avoid false positives
🔗Related repos
junegunn/fzf— Original fuzzy finder inspiration (written in Go); Skim is the Rust spiritual successor with compatible keybindings and CLI interfacesharkdp/fd— Fast directory traversal with Rust; often piped into skim for file selection in shell workflows (ls | sk pattern)BurntSushi/ripgrep— Fast regex search tool in Rust; complementary to skim — ripgrep feeds results, skim filters interactivelyratatui/ratatui— Skim's TUI framework dependency; understanding Ratatui's widget system is essential for modifying the terminal UIcrossterm-rs/crossterm— Cross-platform terminal I/O abstraction layer; required for key event polling and cursor control in skim's event loop
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive unit tests for frizbee matching algorithm integration
The frizbee feature is optional and included by default, but there are no dedicated test files in the benches/ or tests/ directories specifically validating frizbee's matching behavior against the core matcher. This is a high-value contribution since frizbee is a core feature that affects user experience and correctness.
- [ ] Create tests/frizbee_integration.rs to test frizbee-enabled matching vs default matcher
- [ ] Add test cases for edge cases: empty input, special characters, unicode handling with frizbee
- [ ] Reference benches/filter.rs patterns to ensure consistency with existing benchmark structure
- [ ] Validate that frizbee and default matcher produce compatible result ordering
Create missing shell completion tests and validation workflow
The repo has clap_complete and clap_complete_nushell dependencies and shell/ directory with bash completions, but there's no CI validation that completions are generated correctly or tested for regression. The .github/workflows directory shows test.yml and pr.yml exist, but shell completion validation is absent.
- [ ] Add shell completion generation tests in tests/ (bash, zsh, fish validation)
- [ ] Create a GitHub Actions workflow step in .github/workflows/test.yml to validate completion generation doesn't regress
- [ ] Reference clap_mangen usage in src/bin/main.rs to ensure completions match CLI structure
- [ ] Add completion files to .gitignore if they're generated artifacts, or document manual regeneration process
Add integration tests for custom keybinding and action system
The examples/ directory contains custom_action_keybinding.rs, custom_keybinding_actions.rs, and downcast.rs showing advanced APIs, but there are no tests validating the keybinding resolution, custom action execution, or event handling. This is critical for library users relying on extensibility.
- [ ] Create tests/keybinding_integration.rs with test cases covering key parsing, binding resolution, and custom action dispatch
- [ ] Reference examples/custom_action_keybinding.rs and examples/custom_keybinding_actions.rs as test templates
- [ ] Add tests for edge cases: conflicting bindings, invalid key sequences, action chaining
- [ ] Validate that downcast mechanism (from examples/downcast.rs) works correctly in test environment
🌿Good first issues
- Add unit tests for matcher edge cases: examples/fuzzy_matcher_fz.rs exists but src/matcher.rs (or equivalent) likely lacks exhaustive tests for Unicode, empty strings, and special regex characters; write snapshot tests using insta for 5 new matcher scenarios.
- Extend examples with library-only async patterns: examples/async.rs exists, but no example shows using Skim within an existing Tokio runtime (common in web services); create examples/tokio_integration.rs demonstrating spawn + cancel handling.
- Document preview window failure modes: ARCHITECTURE.md mentions preview IPC but no troubleshooting guide; add section to README.md or new PREVIEW_TROUBLESHOOTING.md with signals, timeout, and file descriptor leak diagnostics.
⭐Top contributors
Click to expand
Top contributors
- @LoricAndre — 63 commits
- @dependabot[bot] — 30 commits
- @phanen — 1 commits
- @leaty — 1 commits
- @Xeonacid — 1 commits
📝Recent commits
Click to expand
Recent commits
168ac72— chore(deps): bump tokio from 1.52.1 to 1.52.2 in the cargo-prod group (#1067) (dependabot[bot])e361a8d— chore(ci): readd PR check (#1068) (LoricAndre)ec77fa7— release: v4.6.2 (LoricAndre)c3bac9f— fix(windows): use 1-based cursor position (closes #1065) (LoricAndre)19d2640— chore(deps): bump clap_complete in the cargo-prod group (#1066) (dependabot[bot])8d92d05— release: v4.6.1 (LoricAndre)0457fd2— fix: do not truncate display when longer than text (#1064) (LoricAndre)6fb2cc5— chore(deps): bump tokio from 1.51.1 to 1.52.1 (#1059) (dependabot[bot])87a2536— chore(deps): bump clap from 4.6.0 to 4.6.1 (#1060) (dependabot[bot])44e8aef— chore(deps): bump interprocess from 2.4.0 to 2.4.2 (#1058) (dependabot[bot])
🔒Security observations
The skim codebase demonstrates generally good security practices with optional features properly gated, signed releases via GitHub Actions, and use of modern Rust (1.91+). However, there are several areas of concern: (1) an incomplete dependency specification in Cargo.toml that could affect reproducibility, (2) an invalid Rust edition specification that may cause build issues, (3) aggressive stripping of debug symbols that could hinder security investigations, and (4) the presence of memory safety suppressions that warrant review. The codebase lacks explicit dependency vulnerability scanning in the visible CI/CD configuration, though codecov integration suggests good testing practices. No SQL injection, XSS, or credential hardcoding issues are apparent from the file structure analysis. Docker/infrastructure security appears minimal based on the provided context, suggesting this is primarily a CLI tool. Overall, the project appears well-maintained but would benefit from addressing the configuration issues identified.
- Medium · Incomplete Dependency Version Specification —
Cargo.toml - dependencies section. The Cargo.toml shows a truncated dependency entry for 'log' (version = "0.4."), which appears incomplete. This could lead to unpredictable version resolution and potential security updates being missed. The build system may select unexpected versions of this critical logging library. Fix: Complete the version specification for the 'log' dependency (e.g., 'log = "0.4.21"' or 'log = "0.4"'). Review all dependencies to ensure complete version specifications. - Low · Overly Permissive Rust Edition —
Cargo.toml - edition field. The codebase specifies edition = "2024" in Cargo.toml, which is not a valid Rust edition as of the latest stable releases (valid editions are 2015, 2018, 2021). This may cause build failures or unexpected behavior depending on the Rust compiler version used. Fix: Set edition to a valid value such as '2021'. This ensures compatibility with current and future Rust toolchains. - Low · Aggressive Strip Configuration in Release Build —
Cargo.toml - profile.release section. The release profile includes 'strip = true', which removes all debugging symbols and potentially useful error information. While this reduces binary size, it may complicate security incident investigation and crash analysis. Fix: Consider using 'strip = false' for security-critical deployments, or maintain separate debug and release builds. At minimum, document the trade-off between security investigation capabilities and binary size. - Low · Potential Git Hook Security Issue —
.githooks/pre-commit. The repository includes custom git hooks (.githooks/pre-commit). While hooks can improve code quality, they may be a vector for supply-chain attacks if not properly validated. The hooks are not included in version control protections. Fix: Ensure all git hooks are code-reviewed and tested. Document their purpose and implementation. Consider using tools like husky with verification to ensure hook integrity. - Low · Valgrind Suppression File Present —
.config/valgrind.supp. The presence of .config/valgrind.supp suggests memory safety issues are being suppressed rather than fixed. While Valgrind suppressions are sometimes necessary, they may mask underlying memory safety vulnerabilities. Fix: Review the suppression file to understand which issues are being suppressed. Prioritize fixing the root causes rather than suppressing warnings. Document the rationale for any necessary suppressions. - Low · Development Dependencies Not Isolated —
benches/ directory, Cargo.toml features section. Benchmarking tools and test dependencies (gungraun, custom bench files) are included in the main source tree. While optional features exist, accidental inclusion in production builds is possible. Fix: Ensure benchmark dependencies remain optional and are never included in default builds. Use 'required-features' carefully and test default feature builds in CI.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.