- Rust 46.8%
- TypeScript 46.7%
- CSS 5%
- HTML 0.8%
- Dockerfile 0.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo | ||
| patches | ||
| public | ||
| src | ||
| src-tauri | ||
| tests/e2e | ||
| .gitignore | ||
| bun.lock | ||
| index.html | ||
| LICENSE | ||
| linux-builder.Dockerfile | ||
| onboarding.html | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.json | ||
| vite.config.ts | ||
unimo — desktop launcher (Tauri)
A Spotlight/Raycast-style launcher: a frameless, transparent, always-on-top panel
summoned with Cmd/Ctrl+Space near the cursor. Searches installed apps, built-in
commands, and the web (via the unimo SDK's account.search), and learns from what
you pick.
This is a Tauri 2 port of the Electron desktop.unimo app. The UI is a small
Solid app (src/ui/*.tsx) rendering to light DOM
so the existing global CSS, popover-based dropdowns, and platform data-attributes
keep working; the OS backend is Rust.
Architecture: Rust vs. TypeScript
Accounts, search ranking/merging, the built-in command palette, search history
(frecency), and web search are all business logic and run in TypeScript,
using the unimo-sdk
client SDK for accounts and end-to-end-encrypted storage. Rust is kept to
OS interaction and secrets only:
- Installed-app enumeration, icon extraction, and launching (
src-tauri/src/search/apps.rs) - The favicon disk cache (
favicon.rs) - A generic OS-keychain secret store (
secrets.rs) — opaquesecret_get/secret_set/secret_delete, used by the frontend to persist device seeds and other secrets - Window/tray/global-shortcut/updater management and native app control (quit/reload/devtools)
See src/unimo/ (accounts, backed by the SDK), src/search/ (ranking, history,
command palette, web search), and src/ui/ (the Solid UI: SearchPanel,
ResultItem, ActionTabs, Onboarding, plus the search-state signal graph)
for the TypeScript side.
Web search itself is a plain SDK call: account.search.search(query) /
account.search.suggest(query) (added to unimo-sdk — see vendor/README.md),
ridden over the same authenticated connection as everything else the account does.
There's no separate search-gateway endpoint/token to configure anymore — whatever
backend the account is registered on (its backend URL from onboarding) serves
search too.
Features
- Local search merging three providers by score: installed apps
(macOS
mdfind, Linux.desktop, Windows registry), built-in commands (Settings / Reload / Quit / DevTools), and history (frecency learning) — all ranked/merged in TypeScript (src/search/). - Web search via the unimo SDK's
account.search(typeahead suggestions + full results, reconnect handled by the SDK'sConnection) —src/search/websearch.tsis a thin adapter over it. Degrades gracefully to empty results when offline or logged out. - Icons: app icons (macOS
.icns→ PNG viasips; Linux icon themes) and web favicons (DuckDuckGo service), both lazy-loaded and cached. - Window: cursor-anchored panel, global shortcut toggle, hide-on-blur, tray icon, single-instance, macOS dock-hidden + visible on all Spaces.
- Accounts are registered/logged in via the unimo SDK (post-quantum end-to-end encryption); only the resulting device/recovery seeds are persisted, opaquely, in the OS keychain via Rust's generic secret store.
- Search history at rest is stored in the account's own end-to-end-encrypted
KVcollection (via the SDK) — no bespoke crypto in this app anymore.
Setup
bun install
No .env/gateway config needed — web search rides the logged-in account's own
connection to whatever unimo backend it registered on. Without a logged-in
account, local (apps/commands/history) search still works; web search returns
nothing.
Commands
bun run tauri dev— run dev: builds Rust, opens the window, runs Vite with HMRbun run tauri build— build for production: installers insrc-tauri/target/release/bundle/bun run clean— remove build artifacts (dist/and the Rusttarget/)bun run rebuild— clean rebuild:clean, then a production buildbun run build— frontend only:tsc+vite build→dist/bunx tsc— frontend typecheck;cargo check/cargo clippy(insrc-tauri/) — backend
Notes
- Cmd+Space collides with Spotlight on macOS; if the OS owns it, registration is
logged and skipped — use the tray's Show/Hide instead, or change the modifier in
src-tauri/src/lib.rs(register_shortcut). - Windows app-icon extraction is not implemented (falls back to a default glyph).
- On unsigned dev rebuilds, macOS may prompt for keychain access (the ad-hoc signature changes between builds); signed release builds don't.