Skip to content

dardourimohamed/tauri-background-service

tauri-plugin-background-service

crates.io docs.rs npm License

A Tauri v2 plugin that manages long-lived background service lifecycle across all platforms (Android, iOS, Windows, macOS, Linux).

You implement a single BackgroundService trait on your own struct. The plugin spawns it in a Tokio task, keeps the OS from killing it on mobile, and provides helpers for notifications and event emission. No business logic lives in the plugin — only lifecycle management.

Platform Support

Capability Android iOS Desktop (Win/macOS/Linux)
Service runs in background Foreground Service BGAppRefreshTask + BGProcessingTask Standard Tokio task
OS service mode systemd / launchd (desktop-service feature)
Service survives app close START_STICKY No In-process: No; OS service: Yes
Local notifications Yes Yes Yes

Key features: Structured stop reasons (StopReason), native lifecycle events from OS, full lifecycle status API (getLifecycleStatus()), runtime recovery configuration (configureRecovery()), enhanced validation with severity levels, desktop file-based persistence, iOS UserDefaults persistence for BGTask info.

Installation

Rust

Add the plugin to your app's Cargo.toml:

[dependencies]
tauri = { version = "2" }
tauri-plugin-notification = "2"
tauri-plugin-background-service = "0.7"

npm (TypeScript API)

npm install tauri-plugin-background-service

Quick Start

1. Implement the BackgroundService trait

use async_trait::async_trait;
use tauri::Runtime;
use tauri_plugin_background_service::{BackgroundService, ServiceContext, ServiceError};

pub struct MyService {
    tick_count: u64,
}

impl MyService {
    pub fn new() -> Self {
        Self { tick_count: 0 }
    }
}

#[async_trait]
impl<R: Runtime> BackgroundService<R> for MyService {
    async fn init(&mut self, _ctx: &ServiceContext<R>) -> Result<(), ServiceError> {
        // One-time setup: load config, open handles, seed state
        Ok(())
    }

    async fn run(&mut self, ctx: &ServiceContext<R>) -> Result<(), ServiceError> {
        let mut interval = tokio::time::interval(std::time::Duration::from_secs(10));

        loop {
            tokio::select! {
                _ = ctx.shutdown.cancelled() => break,
                _ = interval.tick() => {
                    self.tick_count += 1;
                    // Emit events to JS
                    let _ = ctx.app.emit("my-service://tick", self.tick_count);
                    // Show local notifications
                    ctx.notifier.show("Tick", "Service is alive");
                }
            }
        }

        Ok(())
    }
}

2. Register the plugin

Register tauri-plugin-notification before the background-service plugin:

fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_notification::init())
        .plugin(tauri_plugin_background_service::init_with_service(
            || MyService::new(),
        ))
        .run(tauri::generate_context!())
        .expect("error while running application");
}

3. Add plugin configuration

In your tauri.conf.json, add the plugin configuration. It can be empty:

{
  "plugins": {
    "background-service": {}
  }
}

4. Use the TypeScript API

import {
  startService,
  stopService,
  isServiceRunning,
  getServiceState,
  onPluginEvent,
} from 'tauri-plugin-background-service';

// Start the service
await startService({ serviceLabel: 'Syncing data' });

// Query detailed service state
const status = await getServiceState();
console.log(status.state); // 'idle' | 'initializing' | 'running' | 'stopped'

// Listen to lifecycle events
const unlisten = await onPluginEvent((event) => {
  switch (event.type) {
    case 'started':
      console.log('Service started');
      break;
    case 'stopped':
      console.log('Service stopped:', event.reason);
      break;
    case 'error':
      console.error('Service error:', event.message);
      break;
  }
});

// Stop the service
await stopService();
unlisten();

Project Layout

tauri-background-service/
├── tauri-plugin-background-service/   Plugin crate (Rust + TypeScript + native)
│   ├── src/                           Rust source (actor loop, trait, models)
│   ├── guest-js/                      TypeScript API bindings
│   ├── android/                       Kotlin foreground service
│   ├── ios/                           Swift BGTaskScheduler
│   ├── examples/                      Usage examples
│   ├── docs/                          Platform guides and API reference
│   └── tests/                         Integration tests
└── test-app/                          Manual test harness (Android device)

Documentation

Development

# Build
cargo build

# Test
cargo test

# Lint
cargo clippy

# Build TypeScript bindings
cd tauri-plugin-background-service/guest-js && npm run build

See Contributing for the full development guide.

Community

License

SPDX-License-Identifier: MIT OR Apache-2.0

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors