Architecture
Rscoop is a Tauri 2 app. Rust backend, SolidJS frontend, talking to each other over Tauri’s IPC bridge.
Rust backend
The backend lives in src-tauri/src/. Here’s how it’s organized:
lib.rsis the entry point. Wires up all Tauri plugins, resolves the Scoop root path, and creates the sharedAppState(cached packages, Scoop directory).commands/has 30+ Tauri commands grouped by domain: search, install, update, uninstall, buckets, doctor, VirusTotal, settings, shims, cache, version switching, and more. These are what the frontend calls.cold_start.rsruns on first launch to preload Scoop metadata. Emitscold-start-finishedandscoop-readyevents that the frontend waits for before rendering.utils.rshas shared helpers for running PowerShell, parsing manifests, caching bucket metadata, and working with shims/shortcuts.tray.rsbuilds the system tray menu from installed Scoop apps. Handles show/hide and app launching.scheduler.rsis the background loop for auto-updating buckets and packages on a configurable interval.
SolidJS frontend
The frontend lives in src/. Five pages, each with its own components:
App.tsxis the root component. Listens for backend lifecycle events, manages the update banner, handles routing.pages/contains SearchPage, InstalledPage, BucketPage, DoctorPage, SettingsPage.hooks/wraps Tauri command calls.useInstalledPackageshandles refreshes,useBucketSearchdoes paginated discovery,usePackageOperationsorchestrates install/update flows.stores/holds reactive state shared across components. Installed packages cache, held packages, view preferences.components/page/mirrors the page structure. Each page has its own subfolder of components.
How data flows
- User clicks something (e.g. “Install”).
- A hook calls the matching Rust command via
@tauri-apps/api/core.invoke. - The Rust command runs the Scoop CLI (or a native helper like git2), streams logs through
tauri-plugin-log, and returns results. - The hook updates SolidJS signals/stores, which re-renders the UI. Completion triggers follow-up refreshes (e.g. reloading the package list).
Caching
- In-memory: installed packages and bucket metadata are cached in
AppStateto avoid hammering Scoop on every render. Invalidated by a fingerprint check (did the apps directory change?). - On-disk: the expanded bucket search index is saved locally so discovery works offline. You control when to refresh it.
- localStorage: view preferences (selected tab, layout mode) persist across restarts via
createStoredSignal.