noahdunnagan /fsearch

Whole-disk file search for macOS: fuzzy names, typo tolerance, indexed content grep. ~1 ms over 8M files.

★ 2,220⑂ 141👁 5▤ 2
RustCreated 2026-10-09
2,220
stars
+0+2
141
forks
5
watchers
–
prs
–
issues
2
releases
–
discussions

README

FSearch

Whole-disk file search for macOS: names in about 0.1 ms, typo-tolerant,
plus indexed search inside files. A CLI with a small daemon, a Rust crate,
or an MCP server for coding agents.


cargo build --release && ./target/release/fsearch install    - ~/.local/bin/fsearch
fsearch fsearch main               find files by name
fsearch 'ext:rs grep:apply_dir'    search inside files


Or skip the Rust toolchain with a release build for Apple Silicon:


curl -L https://github.com/noahdunnagan/fsearch/releases/latest/download/fsearch-aarch64-apple-darwin.tar.gz | tar xz && ./fsearch install


 Speed

M4 Mac mini, a home holding the Linux or the Chromium source tree, vs the
previous version (b88f4e9). Medians; Linux / Chromium.

| | before | now |
|---|---:|---:|
| right file first, name search | 83% / 86% | 93% / 97% |
| right file first, two typos | 11% / 15% | 74% / 93% |
| find a file by name | 0.045 / 0.10 ms | 0.054 / 0.12 ms |
| an edited file greppable | 2.1 s | 1.3 ms |
| a rename or delete visible | 45 / 47 ms | 18 / 15 ms |
| first run, a name in a folder | 7.8 / 7.8 s | 0.18 / 1.2 s |
| first run, every match in the tree | 10.9 / 12.2 s | 2.4 / 10.8 s |
| files grep can search (rg's own set) | 96% / 92% | 99.9% / 99.8% |
| grep, first page | 0.29 / 0.48 ms | 0.33 / 0.65 ms |
| index on disk | 503 / 893 MB | 309 / 600 MB |
| peak memory while indexing | 1.13 / 1.37 GB | 0.77 / 0.94 GB |
| daemon memory | 19 / 100 MB | 21 / 35 MB |

The index is a third smaller while holding a third more text: one 3-bit
filter per file instead of two, compressed posting lists and paths, and
bit-packed name arrays read in place. Grep's first page reads a few more
files for it, and the deeper typo search costs a little on names.

 Queries


fsearch 'readme in:~/Developer'           inside a folder
fsearch 'type:image size:5mb mtime: Privacy & Security, again after each rebuild. Without
access it skips protected folders instead of prompting.

 API

JSON lines over ~/Library/Application Support/FSearch/fsearch.sock, or
fsearch stdio:

json
{"q": "fsearch main", "limit": 20, "offset": 20}
{"op": "grep", "pattern": "apply_dir", "in": "~/Developer", "context": 2}
{"q": "main.rs", "boost": true, "near": "~/Developer/app/src/lib.rs", "git": true}
{"op": "open", "path": "~/Developer/app/src/main.rs"}
{"op": "recent", "in": "~/Developer/app"}


open tells it what you opened; "boost": true ranks those higher for a
while, near favors files close to the one you're in, and recent lists
what you worked on lately. "git": true adds each hit's git status.

For coding agents, fsearch mcp is an MCP server on stdio with
find_files, grep and multi_grep.

Or link the crate:

rust
let engine = fsearch::Engine::start(fsearch::Options { dir: fsearch::default_dir(&home), home: home.clone(), skip: None })?;
let hits = engine.search(&fsearch::Query::parse("fsearch main", &home)?)?;


An app and the CLI share one index: the first process owns it, the rest
follow.

 How it works

- Craw

Snapshot: 2026-11-04T14:00:00Z · Data license Apache-2.0 · JSON