How Meetily Manages and Persists User Recording Preferences

Meetily persists user recording preferences to a JSON file using tauri-plugin-store, with Rust structs defining the schema and Tauri commands exposing read/write operations to the TypeScript frontend.

Meetily is an open-source meeting recording application built with Tauri. The application stores user recording preferences—including save locations, auto-save behavior, and audio device selections—inside a JSON-backed store that survives application restarts. This architecture ensures platform-aware defaults while keeping sensitive configuration data local to the user's machine, as implemented in the Zackriya-Solutions/meetily repository.

The RecordingPreferences Data Model

The core schema for user recording preferences resides in frontend/src-tauri/src/audio/recording_preferences.rs. The RecordingPreferences struct defines every setting that persists across sessions.

Core Configuration Fields

The struct captures five primary configuration areas:

  • save_folder – A PathBuf specifying where recordings are written
  • auto_save – Boolean flag for automatic saving after sessions
  • file_format – Default container format (e.g., "mp4")
  • preferred_mic_device – Optional override for microphone selection
  • preferred_system_device – Optional override for system audio capture

On macOS, an additional field system_audio_backend allows selection between ScreenCaptureKit and CoreAudio.

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RecordingPreferences {
    pub save_folder: PathBuf,
    pub auto_save: bool,
    pub file_format: String,
    #[serde(default)] pub preferred_mic_device: Option<String>,
    #[serde(default)] pub preferred_system_device: Option<String>,
    #[cfg(target_os = "macos")]
    #[serde(default)] pub system_audio_backend: Option<String>,
}

Platform-Specific Default Folders

When no prior preferences exist, get_default_recordings_folder() resolves sensible platform-specific paths:

  • Windows: ~/Music/meetily-recordings
  • macOS: ~/Movies/meetily-recordings
  • Linux: ~/Documents/meetily-recordings

This function ensures users always have a valid write location without manual configuration.

pub fn get_default_recordings_folder() -> PathBuf {
    // Platform-specific home directory resolution
    // Returns appropriate PathBuf for current OS
}

Loading User Recording Preferences from Disk

The load_recording_preferences() function in recording_preferences.rs handles retrieval from persistent storage. It reads from recording_preferences.json via the Tauri store API.

If the store file is missing or contains corrupt data, the function gracefully falls back to RecordingPreferences::default(). On macOS, it also injects the current audio-capture backend into the returned struct.

pub async fn load_recording_preferences<R: Runtime>(app: &AppHandle<R>) -> Result<RecordingPreferences> {
    let store = app.store("recording_preferences.json")?;
    let prefs = if let Some(v) = store.get("preferences") {
        serde_json::from_value(v.clone()).unwrap_or_default()
    } else {
        RecordingPreferences::default()
    };
    Ok(prefs)
}

Saving and Persisting Recording Preferences

Updates flow through save_recording_preferences(), which serializes the struct back into the JSON store. The function performs three critical operations:

  1. Writes the serialized preferences to recording_preferences.json
  2. Ensures the target save_folder exists on disk
  3. On macOS, updates the global audio-capture backend
pub async fn save_recording_preferences<R: Runtime>(app: &AppHandle<R>, prefs: &RecordingPreferences) -> Result<()> {
    let store = app.store("recording_preferences.json")?;
    store.set("preferences", serde_json::to_value(prefs)?);
    store.save()?;
    ensure_recordings_directory(&prefs.save_folder)?;
    #[cfg(target_os = "macos")] { 
        // Backend update logic
    }
    Ok(())
}

Frontend Integration via Tauri Commands

The Rust functions are exposed to the UI layer through async Tauri commands registered in frontend/src-tauri/src/lib.rs (lines 684-692). These commands enable the React/TypeScript frontend to read and modify user recording preferences securely.

Available Commands

  • get_recording_preferences – Returns the current RecordingPreferences struct
  • set_recording_preferences – Writes a new preferences object to disk
  • get_default_recordings_folder_path – Returns the resolved default folder as a string
  • open_recordings_folder – Launches the OS file explorer at the recordings directory
  • select_recording_folder – Placeholder for dialog-based folder selection
  • set_audio_backend – macOS-specific command to switch between ScreenCaptureKit and CoreAudio

Frontend Implementation Examples

Retrieving current preferences:

const prefs = await invoke<RecordingPreferences>('get_recording_preferences');
console.log(`Saving to: ${prefs.save_folder}`);

Updating the save location and auto-save behavior:

await invoke('set_recording_preferences', {
  preferences: {
    ...prefs,
    save_folder: '/Users/me/Movies/meetily-recordings',
    auto_save: false,
  },
});

Launching the recordings folder:

await invoke('open_recordings_folder');

Switching audio backends on macOS:

await invoke('set_audio_backend', { backend: 'coreaudio' });

Persistence Flow

When the application starts, the sidebar provider invokes load_recording_preferences() to initialize UI state. Any user modification triggers set_recording_preferences, which writes changes immediately and creates the recordings folder if needed. Because the store file lives inside Tauri's application data directory, preferences survive restarts and remain isolated per-user.

Summary

  • Storage Mechanism: User recording preferences persist to recording_preferences.json using tauri-plugin-store
  • Rust Implementation: The RecordingPreferences struct in frontend/src-tauri/src/audio/recording_preferences.rs defines the schema with platform-aware defaults
  • Data Integrity: Missing or corrupt stores automatically fall back to sensible defaults via get_default_recordings_folder()
  • Frontend Access: TypeScript invokes Tauri commands (get_recording_preferences, set_recording_preferences) to read and write settings
  • macOS Specifics: Additional system_audio_backend field supports toggling between ScreenCaptureKit and CoreAudio capture engines

Frequently Asked Questions

Where does Meetily store user recording preferences?

Meetily stores preferences in a file named recording_preferences.json managed by tauri-plugin-store. This file resides in Tauri's application data directory, keeping settings private and isolated per-user on the local machine.

What happens if the preferences file is missing or corrupted?

The load_recording_preferences() function detects missing or invalid JSON and returns RecordingPreferences::default(). This ensures the application always starts with functional settings, using platform-specific default folders for the recording directory.

How does Meetily handle audio device selection across platforms?

The RecordingPreferences struct includes optional preferred_mic_device and preferred_system_device fields for hardware selection. On macOS, an additional system_audio_backend field allows users to choose between ScreenCaptureKit and CoreAudio for system audio capture, with dedicated Tauri commands exposing these controls to the frontend.

Can users change the default recording folder location?

Yes. The frontend invokes set_recording_preferences with a new save_folder path, which triggers save_recording_preferences() to persist the change and create the directory if it doesn't exist. The select_recording_folder command also provides a dialog-based picker for folder selection.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →