The Problem
Developers building Tauri desktop apps need a lightweight, privacy‑first analytics solution without pulling in heavyweight SDKs or external services. Aptabase fills that gap, but integrating it manually requires boiler‑plate code for event enrichment, background flushing, and permission handling.
What This Does
The repository delivers a Tauri plugin (tauri-plugin-aptabase) that exposes a Rust EventTracker trait and a JavaScript guest API (@aptabase/tauri). Core logic lives in the src/ directory:
src/lib.rsbuilds the plugin, implementswith_options, registers thetrack_eventcommand and wires the panic hook.src/client.rscreates a per‑sessionAptabaseClient, generates a session ID, and starts a background poller that periodically flushes queued events.src/dispatcher.rsholds the in‑memory event queue (enqueue,dequeue_many) and theflush/flush_blockinghelpers that ship payloads to the Aptabase endpoint.src/sys.rsgathers static system properties (OS, version) that are merged into every event.
The examples/helloworld folder shows a minimal Tauri app that imports the plugin via Cargo.toml and calls app.track_event("app_started", None) from Rust and trackEvent("save_settings") from JavaScript.
How It Is Wired
Execution starts in the example’s Rust entry point examples/helloworld/src-tauri/src/lib.rs → run() (line 14). run() creates a tauri::Builder, attaches the plugin with tauri_plugin_aptabase::Builder::new("<APP_KEY>").build(), and hands control to Tauri’s runtime.
During plugin construction (src/lib.rs::new → with_options), the following chain is established:
newcreates aConfig(src/config.rs) and aClient(src/client.rs::new).Client::newcallsnew_session_idandstart_polling, which spawns an async task that repeatedly invokesflush_blocking.- When the app calls
track_event, the command defined insrc/commands.rsforwards the payload toClient::enqueue(src/dispatcher.rs::enqueue). flush_blocking(called by the background poller and manually viahandler.flush_events_blocking()) triggersflush_events_blocking → flush_blocking → is_emptyand, if the queue is non‑empty,dequeue_manyfollowed by a network POST to Aptabase (the actual HTTP call lives in the generatedwebview-srcbundle, not shown in the static analysis).
The widest blast radius lies in src/dispatcher.rs::enqueue and flush_blocking – they are the only functions that touch the queue and ultimately perform network I/O, and they are invoked from both the background poller and any explicit flush call.
No circular imports are present; the internal module graph contains 7 modules with zero import edges, indicating a flat dependency structure.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/tauri-plugin-aptabase
cd tauri-plugin-aptabase
# Build the plugin (Rust)
cargo build --release
# Install JS guest bindings for the example
cd examples/helloworld
npm install # reads examples/helloworld/package.json
# Provide your Aptabase key (replace <YOUR_APP_KEY>)
# Either edit the Rust code in src-tauri/src/lib.rs or set an .env file:
# APTABASE_KEY=your_key_here (dotenvy_macro reads .env in src-tauri)
# Then run the example
cargo tauri dev # requires Tauri CLI installed globally
The plugin is also consumable by other Tauri projects: add the dependency to the app’s src-tauri/Cargo.toml as shown in the README and call app.track_event(name, properties) from Rust or trackEvent from JavaScript.
Real‑World Use
A SaaS desktop client can embed this plugin to record app_started, feature_used, and app_exited events. The client’s main process registers the plugin at startup, tracks a handful of high‑level events, and relies on the built‑in background flush to send data without blocking UI threads. No additional server infrastructure is required beyond Aptabase’s hosted endpoint.
Code Health & Issues
- High – No test suite – 11 source files, zero test files. Add unit/integration tests for public APIs (
track_event, queue handling) and a CI step to run them. - High – Missing Cargo.lock –
Cargo.tomlpresent, lockfile absent. Runcargo generate-lockfileand commit the resultingCargo.lockto guarantee reproducible builds. - High – No CI pipeline – No
.github/workflowsor other CI config. Add a GitHub Actions workflow that builds the plugin and runs the test suite on push/PR. - Medium – Dependabot not configured – No
.github/dependabot.yml. Introduce a Dependabot config coveringcargoandnpmto receive automated security updates.
No Dockerfile, secret leakage, or license issues were detected; the repository includes an MIT LICENSE.
The Bottom Line
The plugin provides a clean, minimal integration point for Aptabase analytics in Tauri apps, with clear separation between event queuing, system enrichment, and network flushing. However, the lack of tests, lockfile, and CI makes it risky for production use until those gaps are addressed. Teams comfortable managing their own quality gates can adopt it quickly; otherwise, invest in the missing hygiene before shipping.