How to Configure and Switch Between Whisper vs Parakeet Transcription Engines in Meetily

Meetily allows you to switch between Whisper and Parakeet transcription engines by updating the transcriptModelConfig object in the React context, which persists via Tauri commands to a local SQLite database without requiring an app restart.

Meetily, an open-source meeting transcription application by Zackriya-Solutions, provides two native transcription backends optimized for different hardware and latency requirements. Understanding how to configure Whisper vs Parakeet transcription engines enables you to balance accuracy against real-time performance based on your CPU, GPU, or Apple Silicon capabilities. The configuration system spans the React frontend in frontend/src/contexts/ConfigContext.tsx and Rust backend commands defined in frontend/src-tauri/src/commands.rs.

Configuration Architecture

Meetily defines transcription engine settings through the TranscriptModelProps interface, which supports multiple providers including the two local engines:

export interface TranscriptModelProps {
  provider: 'localWhisper' | 'parakeet' | 'deepgram' | 'elevenLabs' | 'groq' | 'openai';
  model: string;          // e.g., "large-v3-turbo" or "parakeet-tdt-0.6b-v3-int8"
  apiKey?: string | null; // Only required for cloud providers
}

When you select Whisper (localWhisper), the app routes transcription requests to the whisper-rs based Rust engine. Selecting Parakeet routes to the NVIDIA NeMo-ONNX runtime optimized for Apple Silicon and modern NVIDIA GPUs. Both engines are selected at the UI level and stored in the transcriptModelConfig state object.

Where Settings Are Stored

The configuration exists in two layers: React context for immediate UI state and Rust/SQLite for persistence across sessions.

React Context: The ConfigContext.tsx file creates the context, loads saved configuration on mount via configService.getTranscriptConfig(), and exposes setTranscriptModelConfig to update settings. According to the source code at lines 108-113 in ConfigContext.tsx, this context serves as the single source of truth for the entire application.

Rust Backend: The helpers api_save_transcript_config and api_get_transcript_config in src-tauri/src/commands.rs handle database operations. When you update the provider, the React context invokes these Tauri commands to write the config to a local SQLite database, ensuring your preference persists after closing the app.

Switching Engines via the UI

The transcription settings flow follows a specific component hierarchy that handles engine selection:

  1. Open Settings → Transcription to load the TranscriptSettings component, which renders a provider selector (lines 10-30 in TranscriptSettings.tsx).

  2. When you select "Local Whisper" or "Parakeet" from the dropdown, the component updates the local UI state and conditionally renders either WhisperModelManager or ParakeetModelManager for model-specific configuration.

  3. Upon selecting a concrete model, the component calls setTranscriptModelConfig({ provider, model }), which simultaneously updates the React context and triggers api_save_transcript_config to persist the change.

  4. During recording initialization, useRecordingStart checks engine readiness via checkParakeetReady() or the Whisper equivalent, ensuring the selected model is downloaded and initialized before transcription begins.

Default Model Selection

If you have never configured a transcription engine, Meetily seeds the configuration with default values defined in frontend/src/constants/modelDefaults.ts:

export const DEFAULT_WHISPER_MODEL = 'large-v3-turbo';
export const DEFAULT_PARAKEET_MODEL = 'parakeet-tdt-0.6b-v3-int8';

By default, Meetily selects the Parakeet provider with the parakeet-tdt-0.6b-v3-int8 model. You can override these defaults by manually setting transcriptModelConfig in the context.

JavaScript Wrappers and Rust Communication

Both transcription engines expose identical JavaScript APIs that forward to specialized Rust commands:

Whisper: The WhisperAPI class in frontend/src/lib/whisper.ts (lines 14-34) exposes static methods like whisper_init, whisper_get_available_models, and whisper_download_model. These methods invoke Tauri commands that manage the whisper-rs runtime.

Parakeet: The ParakeetAPI class in frontend/src/lib/parakeet.ts (lines 52-82) provides parallel methods: parakeet_init, parakeet_get_available_models, and parakeet_download_model. These interface with the NVIDIA NeMo-ONNX runtime in the Rust layer.

Both wrappers emit progress events (model-download-progress for Whisper, parakeet-model-download-progress for Parakeet) and completion signals that the UI uses to display download status.

Runtime Switching Without Restart

Because the provider is stored in React context, you can switch engines programmatically at any time:

import { useConfig } from '@/contexts/ConfigContext';
import { DEFAULT_WHISPER_MODEL, DEFAULT_PARAKEET_MODEL } from '@/constants/modelDefaults';

function EngineSwitcher() {
  const { setTranscriptModelConfig } = useConfig();

  const switchToWhisper = () => {
    setTranscriptModelConfig({
      provider: 'localWhisper',
      model: DEFAULT_WHISPER_MODEL,
      apiKey: null,
    });
  };

  const switchToParakeet = () => {
    setTranscriptModelConfig({
      provider: 'parakeet',
      model: DEFAULT_PARAKEET_MODEL,
      apiKey: null,
    });
  };

  return (
    <>
      <button onClick={switchToWhisper}>Use Whisper</button>
      <button onClick={switchToParakeet}>Use Parakeet</button>
    </>
  );
}

When setTranscriptModelConfig executes, it updates the global state and persists to the backend immediately. Subsequent recordings automatically use the newly selected engine.

Ensuring Model Availability Before Recording

To avoid transcription failures, verify the selected model is downloaded before starting a session:

import { WhisperAPI } from '@/lib/whisper';
import { ParakeetAPI } from '@/lib/parakeet';

async function ensureModelReady(provider: 'localWhisper' | 'parakeet', model: string) {
  if (provider === 'localWhisper') {
    await WhisperAPI.init();
    const models = await WhisperAPI.getAvailableModels();
    if (!models.find(m => m.name === model && m.status === 'Available')) {
      await WhisperAPI.downloadModel(model);
    }
  } else {
    await ParakeetAPI.init();
    const models = await ParakeetAPI.getAvailableModels();
    if (!models.find(m => m.name === model && m.status === 'Available')) {
      await ParakeetAPI.downloadModel(model);
    }
  }
}

The validateModelReady command checks that model files exist in the models/ directory and can be loaded into GPU memory, returning a status string or error if initialization fails.

Summary

  • Configuration Interface: Use TranscriptModelProps with provider: 'localWhisper' or 'parakeet' to specify your engine.
  • Persistence: Settings save automatically via api_save_transcript_config to a local SQLite database through Tauri commands.
  • UI Components: TranscriptSettings.tsx coordinates engine selection, delegating to WhisperModelManager or ParakeetModelManager for model-specific UI.
  • Runtime Switching: Call setTranscriptModelConfig() from useConfig() to switch engines instantly without restarting the application.
  • Model Defaults: Whisper defaults to large-v3-turbo; Parakeet defaults to parakeet-tdt-0.6b-v3-int8 as defined in modelDefaults.ts.

Frequently Asked Questions

How do I switch from Whisper to Parakeet without restarting Meetily?

You can switch engines at runtime by calling setTranscriptModelConfig() from the ConfigContext. Update the provider field to 'parakeet' and specify the model name (e.g., 'parakeet-tdt-0.6b-v3-int8'). The change persists immediately via the Tauri command api_save_transcript_config and takes effect on the next recording session.

Where does Meetily store my transcription engine preference?

Meetily stores the configuration in a local SQLite database accessed through Rust commands. The React context in ConfigContext.tsx loads this configuration on app mount using configService.getTranscriptConfig() and saves updates via api_save_transcript_config. This ensures your engine selection persists across application restarts.

What are the key differences between Whisper and Parakeet in Meetily?

Whisper (via whisper-rs) provides highest accuracy transcription and runs on CPU or GPU (Metal/CUDA/Vulkan), making it ideal for post-meeting processing where accuracy matters more than speed. Parakeet (via NVIDIA NeMo-ONNX) offers real-time, low-latency transcription optimized for Apple Silicon and recent NVIDIA GPUs, making it better suited for live captioning during active meetings.

How do I check if my selected transcription model is downloaded?

Use the respective API class to check model status before recording. For Whisper, call WhisperAPI.getAvailableModels() and verify the model object has status === 'Available'. For Parakeet, use ParakeetAPI.getAvailableModels(). If the model is missing, invoke downloadModel() on the appropriate API class to fetch it from the remote repository.

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 →