Skip to main content

Desktop & mobile

PlanningSup can be installed as a native application on desktop and mobile platforms using Tauri, a Rust-based framework for building cross-platform apps with web technologies.

Supported platforms

WindowsWindows 10+ (64-bit)

macOSmacOS 10.15+ (Intel and Apple Silicon)

LinuxUbuntu 20.04+, Fedora 36+, and other modern distros

AndroidAndroid 7.0+ (API level 24+)
iOS support is experimental and requires building from source. Use the web app or PWA instead for the best iOS experience.

Installation

Native builds are not yet available for public download. To run the desktop or mobile app, you must build from source.

Prerequisites

1

Install Rust

Follow the instructions at rustup.rs
2

Install Bun

Download from bun.sh
3

Install system dependencies

Linux:
sudo apt install libwebkit2gtk-4.0-dev libssl-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev
macOS: Xcode Command Line Tools (pre-installed on most systems)Windows: Microsoft Visual Studio C++ Build Tools

Build for desktop

# Clone the repository
git clone https://github.com/kernoeb/PlanningSup.git
cd PlanningSup

# Install dependencies
bun install

# Build the Tauri app
cd apps/app
VITE_AUTH_ENABLED=true VITE_BACKEND_URL=https://planningsup.app bun run tauri build
The compiled app will be in apps/app/src-tauri/target/release/bundle/:
  • Windows: .msi installer
  • macOS: .dmg disk image
  • Linux: .deb or .AppImage

Build for Android

1

Install Android Studio

Download from developer.android.com
2

Set up Android SDK

Accept licenses:
sdkmanager --licenses
3

Add Android target to Tauri

cd apps/app
bun run tauri android init
4

Build the APK

VITE_AUTH_ENABLED=true VITE_BACKEND_URL=https://planningsup.app bun run tauri android build
The APK will be in apps/app/src-tauri/gen/android/app/build/outputs/apk/.
Android builds require a signing key for production. Use bun run tauri android build --debug for testing.

Features

The native apps have feature parity with the web app, plus:

Faster startupNative binary loads instantly without browser overhead

System notifications(Planned) Get notified before classes start

Offline-firstEmbedded database for faster data access

Native window controlsMinimize, maximize, and close like any desktop app

Architecture

The Tauri app embeds the Vue web app inside a WebView (system browser engine):
  • Windows: Edge WebView2
  • macOS: WKWebView
  • Linux: WebKitGTK
  • Android: Android System WebView
The Rust backend provides:
  • Window management
  • File system access (for backups, exports, etc.)
  • Deep link handling (for OAuth redirects)
// apps/app/src-tauri/src/main.rs
fn main() {
    tauri::Builder::default()
        .plugin(tauri_plugin_deep_link::init())
        .plugin(tauri_plugin_opener::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

OAuth in native apps

Native apps use deep links to handle OAuth redirects:
1

User clicks 'Sign in with Discord'

The app opens the OAuth URL in the system browser
2

User authorizes on Discord

Discord redirects to planningsup://auth-callback/discord?code=...
3

Deep link opens the app

The Tauri app intercepts the deep link and extracts the OAuth code
4

App completes authentication

The app exchanges the code for a session cookie via the API
// apps/web/src/composables/useAuth.ts
if (IS_TAURI) {
  const { onOpenUrl } = await import('@tauri-apps/plugin-deep-link')
  
  await onOpenUrl(async (urls) => {
    const url = urls[0]
    if (url.startsWith('planningsup://auth-callback/')) {
      const urlObj = new URL(url)
      const provider = urlObj.pathname.split('/')[1]
      
      const callbackUrl = new URL(`${BACKEND_URL}/api/auth/callback/${provider}${urlObj.search}`)
      callbackUrl.searchParams.set('client', 'tauri')
      
      await fetch(callbackUrl, { credentials: 'include' })
      window.location.reload()
    }
  })
}
See apps/web/src/composables/useAuth.ts:25-76 for the full implementation.
Passkeys (WebAuthn) are not supported in Tauri apps. Use social login instead.

Configuration

The Tauri app is configured in apps/app/src-tauri/tauri.conf.json:
{
  "productName": "PlanningSup",
  "version": "0.1.0",
  "identifier": "app.planningsup",
  "bundle": {
    "active": true,
    "targets": ["msi", "deb", "appimage", "dmg"],
    "icon": ["icons/icon.png"],
    "deeplink": {
      "schemes": ["planningsup"]
    }
  }
}

Build options

Customize the build via environment variables:
# Point to a different backend (e.g., localhost for testing)
VITE_BACKEND_URL=http://localhost:20000 bun run tauri dev

# Disable authentication
VITE_AUTH_ENABLED=false bun run tauri build

Limitations

Native apps have some limitations:
  • No auto-updates: You must download new versions manually (Tauri Updater plugin not yet configured)
  • Larger download size: ~10-20 MB vs. less than 1 MB for the web app
  • Platform-specific bugs: WebView engines have quirks (e.g., missing CSS features on Linux)

Development

To run the Tauri app in development mode:
cd apps/app
bun run dev  # Starts Vite dev server + Tauri window
Hot reload is enabled for the Vue frontend, but Rust changes require a restart.

Debugging

Open the WebView DevTools:
  • Windows / Linux: Right-click → Inspect
  • macOS: Right-click → Inspect Element
Rust logs are printed to the terminal where you ran bun run dev.

Packaging for distribution

Code signing

For production releases, sign the binaries:
  • macOS: Use codesign with an Apple Developer certificate
  • Windows: Use signtool with a code signing certificate
  • Linux: No signing required (though AppImages can be signed)

Distributing the app

Options for distributing native builds:
  1. GitHub Releases: Upload .msi, .dmg, .deb, etc. as release assets
  2. App stores: Publish to Microsoft Store, Mac App Store, or Google Play
  3. Self-hosted: Host the binaries on your own server with download links
PlanningSup is not yet published to app stores. Check the GitHub repository for updates.

Comparison: PWA vs. native app

FeaturePWATauri Native
Install sizeLess than 1 MB10-20 MB
Offline support✅ (Service Worker)✅ (Embedded DB)
Auto-updates❌ (manual)
System notifications⚠️ (browser-dependent)✅ (planned)
OAuth / PasskeysOAuth only
PerformanceGoodSlightly better
Cross-platform
For most users, the PWA is the best option. Use the native app if you need deeper system integration or prefer a standalone binary.

Next steps

Web app

Learn about the full-featured web version

Browser extension

Install the Chrome extension for quick access

Build docs developers (and LLMs) love