GitHub - kelvinolabanji/echo · GitHub
/" data-turbo-transient="true" />
Skip to content
Search/
Sign in<br>Sign upAppearance settings
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
kelvinolabanji
echo
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Latest commit
History<br>38 Commits<br>38 Commits
Folders and files<br>NameNameLast commit message<br>Last commit date<br>backend
backend
frontend/EchoApp
frontend/EchoApp
screenshots
screenshots
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
echo-setup.iss
echo-setup.iss
View all files
Repository files navigation
Echo
A fully local, offline semantic image search tool for Windows. Describe what you're looking for in plain English — "sunset over water," "my dog on the couch," "receipt from last week" — and Echo finds matching photos instantly, without ever sending anything to the cloud.
No account. No internet required after setup. No cloud storage of your photos or their embeddings. Everything runs on your machine.
How it works
Echo indexes your photos locally using CLIP (openai/clip-vit-base-patch32), which turns both images and text descriptions into vectors in the same embedding space. Searching just means turning your query into a vector and finding the closest image vectors with FAISS. All of this happens on-device — the model, the index, and your photos never leave your computer.
Features
Global hotkey (Win+Shift+F) summons a floating search panel from anywhere in Windows
Instant, as-you-type search across all your indexed folders
Automatic first-run setup — indexes your Pictures folder automatically on first launch
Live folder management — add/remove indexed folders, with real-time progress
File system watching — new photos dropped into an indexed folder get picked up automatically
Tray notifications for indexing start/completion
UI that feels like a native Windows feature, not a third-party app
Fully offline — after initial setup, no internet connection is required
Tech stack
Backend — Python 3.11, FastAPI, CLIP via HuggingFace Transformers, FAISS, SQLite<br>Frontend — C# / .NET 8, WinForms, WebView2 (HTML/CSS/JS UI), DWM APIs for acrylic blur
Architecture
echo/<br>├── backend/<br>│ ├── main.py — FastAPI app + all endpoints<br>│ ├── model.py — CLIP model loading<br>│ ├── indexer.py — image embedding + FAISS indexing<br>│ ├── searcher.py — text query embedding + search<br>│ ├── database.py — SQLite operations<br>│ ├── watcher.py — filesystem watcher for auto-indexing<br>│ ├── paths.py — resolves where user data vs. bundled resources live<br>│ └── echo-backend.spec — PyInstaller build spec<br>├── frontend/EchoApp/<br>│ ├── Program.cs — entry point<br>│ ├── BootstrapAppContext.cs — first-run backend setup, inside the message loop<br>│ ├── AppContext.cs — tray icon, hotkey, first-run auto-indexing<br>│ ├── BackendManager.cs — spawns/manages the Python backend process<br>│ ├── BackendDownloader.cs — downloads the backend package on first run<br>│ ├── IndexingWatcher.cs — polls indexing progress, tray notifications<br>│ ├── SearchWindow.cs — floating search UI<br>│ ├── FolderManagerWindow.cs — folder management UI<br>│ ├── EchoBridge.cs — JS ↔ C# bridge for the WebView2 UI<br>│ └── ui/ — HTML/CSS/JS frontend<br>└── echo-setup.iss — Inno Setup installer script
Why the installer is shaped the way it is
The backend bundles CLIP, PyTorch, Transformers, and FAISS — 600MB+ once packaged, which is too large for a lightweight installer. So the installer ships only the (small) frontend; on first launch, the app downloads the backend package from this repo's Releases, verifies it with a SHA-256 checksum, and extracts it — a one-time setup step with its own progress window.
User data (the SQLite database, FAISS index, and thumbnail cache) lives in %LOCALAPPDATA%\Echo, independent of wherever the app itself is installed.
Installation
Download the latest installer from the Releases page and run it. On first launch, Echo will download and set up its search engine (a few hundred MB, one-time) before it's ready to use.
Running from source
Backend:
cd backend<br>python -m venv .venv<br>.venv\Scripts\Activate.ps1<br>pip install -r requirements.txt<br>uvicorn main:app --reload
Frontend:
cd frontend/EchoApp<br>dotnet run
Building the installer yourself
# 1. Build the backend<br>cd backend<br>pyinstaller echo-backend.spec
# 2. Zip and host it (e.g. as a GitHub Release asset), then update the<br># BackendDownloadUrl and ExpectedSha256 constants in BackendDownloader.cs
# 3. Publish the frontend<br>cd frontend/EchoApp<br>dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true
# 4. Compile echo-setup.iss with Inno Setup
Known limitations
CLIP performs slighty better on real photos than on...