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.rs builds the plugin, implements with_options, registers the track_event command and wires the panic hook.
  • src/client.rs creates a per‑session AptabaseClient, generates a session ID, and starts a background poller that periodically flushes queued events.
  • src/dispatcher.rs holds the in‑memory event queue (enqueue, dequeue_many) and the flush/flush_blocking helpers that ship payloads to the Aptabase endpoint.
  • src/sys.rs gathers 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:

  1. new creates a Config (src/config.rs) and a Client (src/client.rs::new).
  2. Client::new calls new_session_id and start_polling, which spawns an async task that repeatedly invokes flush_blocking.
  3. When the app calls track_event, the command defined in src/commands.rs forwards the payload to Client::enqueue (src/dispatcher.rs::enqueue).
  4. flush_blocking (called by the background poller and manually via handler.flush_events_blocking()) triggers flush_events_blocking → flush_blocking → is_empty and, if the queue is non‑empty, dequeue_many followed by a network POST to Aptabase (the actual HTTP call lives in the generated webview-src bundle, 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.toml present, lockfile absent. Run cargo generate-lockfile and commit the resulting Cargo.lock to guarantee reproducible builds.
  • High – No CI pipeline – No .github/workflows or 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 covering cargo and npm to 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.