Fast, offline code search. Indexes a source tree into a local SQLite database and answers full-text and fuzzy filename queries in milliseconds.
$ devfind index ~/projects/myapp
Indexed: 14 832 files
Skipped: 421 files
Bytes: 87 412 904
Time: 3.41s
$ devfind search "thread pool"
[5.82] ~/projects/myapp/src/worker/thread_pool.h
23: ThreadPool& operator=(const ThreadPool&) = delete;
$ devfind find threadpool
~/projects/myapp/src/worker/thread_pool.h 0.47
~/projects/myapp/src/worker/thread_pool.cpp 0.41Requires CMake 3.20+, a C++17 compiler (GCC 11+, Clang 14+, or MSVC 17+), and Ninja or Make. All other dependencies are fetched at configure time.
git clone https://github.com/valetivivek/devfind
cd devfind
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build -jThe devfind binary lands in build/.
devfind index <path> # crawl and index a tree
devfind search "<query>" # BM25 full-text search
devfind find <pattern> # fuzzy filename search
devfind stats # index statistics
devfind watch <path> # re-index on file changes
devfind serve --ui ui/dist # HTTP server + React UI on :7777
devfind bench # benchmark suiteGlobal flags (before the subcommand): --index-path <path>, --log-level <trace|debug|info|warn|error>.
Per-command flags: --limit, --type, --json, --no-snippet, --port, --host.
cd ui && npm install && npm run build && cd ..
build/devfind serve --port 7777 --ui ui/distOpen http://localhost:7777 for the dark-mode search interface with keyboard navigation.
| Method | Path | Params |
|---|---|---|
| GET | /api/search |
q, limit, type |
| GET | /api/find |
q, limit |
| GET | /api/stats |
– |
| GET | /health |
– |
All responses are JSON with CORS headers set.
A walker thread enumerates the tree, a pool of tokenizer workers (hardware_concurrency - 2) processes files in parallel, and a single writer thread batches results into a WAL-mode SQLite database. Tokens are split on non-alphanumeric boundaries and camelCase transitions, lowercased, and stored as packed uint32_t position blobs. Queries score candidates with Okapi BM25 (k1 = 1.5, b = 0.75). A trigram index over basenames powers fuzzy filename matching. Incremental re-indexing skips files whose mtime and size are unchanged.
Full design rationale and tradeoff tables are in DECISIONS.md.
MIT. See LICENSE.