Onboarding Flow for First-Time Users in Meetily: Steps and State Management

Meetily guides first-time users through a four-step onboarding wizard—Welcome, Setup Overview, Model Downloads, and macOS Permissions—that is fully state-managed by the OnboardingContext React context and persisted via Tauri commands.

The first-time user onboarding flow in Meetily prepares the local environment before any meeting can be processed. According to the Zackriya-Solutions/meetily source code, the frontend orchestrates this setup through a deterministic wizard that initializes the database, downloads required AI models, and requests system permissions. All progression and status flags are centralized in a single React context to ensure consistent state across steps and app restarts.

Meetily Onboarding Steps for First-Time Users

The wizard is rendered by [OnboardingFlow.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/components/onboarding/OnboardingFlow.tsx), which mounts the appropriate step component based on the currentStep value from context.

Welcome Step

The WelcomeStep is the entry point for every new installation. It introduces Meetily’s core features and offers a single call-to-action that advances the user to the next stage.

Setup Overview Step

The SetupOverviewStep handles database initialization. It detects existing legacy databases, checks for a Homebrew-managed database on macOS, or creates a fresh SQLite database if none are found. The step surfaces real-time status so the user knows whether the environment is ready.

Download Progress Step

The DownloadProgressStep starts background downloads of the speech-recognition model Parakeet and the selected summarisation model. These downloads are recommended by the built-in AI helper defined in [frontend/src/lib/onboarding-summary-model.ts](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/lib/onboarding-summary-model.ts). Progress bars reflect live percentages and detailed metrics such as downloaded megabytes and transfer speed.

Permissions Step (macOS Only)

The final PermissionsStep is gated behind a platform check and only renders when currentStep === 4 on macOS. It requests microphone, system-audio, and screen-recording permissions. The step can also be skipped, which sets the permissionsSkipped flag in context.

State Management with OnboardingContext

All onboarding state lives inside [frontend/src/contexts/OnboardingContext.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/contexts/OnboardingContext.tsx). The provider wraps the entire application in [frontend/src/app/layout.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/app/layout.tsx), making the state available anywhere via the useOnboarding() hook.

Core State Variables

The context tracks progression and resource readiness through several key flags:

  • currentStep — An integer from 1 to 4 that drives which step component is visible.
  • databaseExists — A boolean that becomes true once the local SQLite database is verified or created via checkDatabaseStatus.
  • parakeetDownloaded and summaryModelDownloaded — Booleans that signal whether each AI model is present locally.
  • parakeetProgress and summaryModelProgress — Numeric percentages from 0 to 100 used for download bars.
  • parakeetProgressInfo and summaryModelProgressInfo — Detailed metadata including downloaded megabytes, total megabytes, and speed in Mbps.
  • selectedSummaryModel and recommendedSummaryModel — Strings managed with help from the onboarding-summary-model helper to decide which summarisation engine to pull.
  • permissions — An object shaped { microphone, systemAudio, screenRecording } with status values such as granted, denied, or not_determined.
  • permissionsSkipped — A boolean set when the user elects to bypass the permissions screen.
  • isBackgroundDownloading — A boolean that stays true while any model download is active in the background.

Step components never mutate state directly. Instead they call navigation utilities exposed by the context:

  • goNext() — Advances currentStep by one without exceeding 4.
  • goPrevious() — Moves currentStep back by one without dropping below 1.
  • goToStep(stepNumber) — Jumps to an explicit step index for targeted navigation.

These helpers update setCurrentStep safely so the UI always stays in sync.

Lifecycle and Side Effects

A mount-time useEffect inside the context performs three critical tasks:

  1. Loads any previously saved onboarding status by calling the Tauri command loadOnboardingStatus.
  2. Checks whether a database already exists through checkDatabaseStatus.
  3. Begins silent background preparation via initializeDatabaseInBackground so the Setup Overview step is not blocked.

Additional listeners subscribe to Tauri events such as parakeet-model-download-progress and builtin-ai-download-progress. As the Rust backend emits progress payloads, the context updates the corresponding React state for live UI feedback.

Persistence and Auto-Save

React state is mirrored to disk through the Tauri command save_onboarding_status_cmd. The write is debounced to roughly one second and is deliberately suppressed while the completion routine is running. This prevents race conditions caused by rapid state churn during large downloads.

Completing the Onboarding Flow

When the user finishes the wizard, completeOnboarding() is invoked from the Permissions step or a final action handler. The routine:

  1. Sets an isCompletingRef flag to halt the auto-save loop.
  2. Ensures the selected summarisation model is ready, triggering a download if necessary.
  3. Calls the complete_onboarding Tauri command with the chosen model name.
  4. Persists the final status with completed: true and clears the completion flag.

Code Examples

Wrapping the Application with OnboardingProvider

The context provider is imported and applied at the root layout so every page can access onboarding state:

// frontend/src/app/layout.tsx
import { OnboardingProvider } from '@/contexts/OnboardingContext';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <OnboardingProvider>{children}</OnboardingProvider>
      </body>
    </html>
  );
}

Individual step components consume the context to move the user forward:

import { useOnboarding } from '@/contexts/OnboardingContext';

export function WelcomeStep() {
  const { goNext } = useOnboarding();

  return (
    <div>
      <h2>Welcome to Meetily</h2>
      <button onClick={goNext}>Get Started</button>
    </div>
  );
}

Triggering Background Model Downloads

The Download Progress step initiates fetches for both the Parakeet and summarisation models:

const { startBackgroundDownloads, recommendedSummaryModel } = useOnboarding();

useEffect(() => {
  startBackgroundDownloads({
    includeParakeet: true,
    includeSummary: true,
    summaryModel: recommendedSummaryModel,
  });
}, []);

Listening to Download Progress

Inside [OnboardingContext.tsx](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src/contexts/OnboardingContext.tsx), progress events from the Tauri backend update the UI state in real time:

useEffect(() => {
  const unlisten = listen('builtin-ai-download-progress', (e) => {
    // Updates `summaryModelProgress` and `summaryModelProgressInfo`
  });
  return () => unlisten.then(fn => fn());
}, [selectedSummaryModel]);

Summary

  • Meetily exposes a four-step onboarding wizard—Welcome, Setup Overview, Download Progress, and macOS Permissions—rendered by OnboardingFlow.
  • All state is owned by OnboardingContext, including the current step index, database existence flags, model-download metrics, and permission statuses.
  • Navigation is handled through goNext, goPrevious, and goToStep so step components remain stateless UI layers.
  • State is auto-saved to disk via debounced Tauri commands, and completion is finalized by calling complete_onboarding on the Rust backend.
  • The provider is mounted once in layout.tsx, making onboarding progress available throughout the React tree.

Frequently Asked Questions

What are the exact steps in the Meetily onboarding flow?

The flow contains four sequential stages: a Welcome screen, a Setup Overview that initializes the local database, a Download Progress screen that fetches the Parakeet and summarisation models, and a Permissions screen that requests microphone, system-audio, and screen-recording access on macOS.

How does OnboardingContext persist state across app restarts?

OnboardingContext loads saved progress on mount through the loadOnboardingStatus Tauri command and continuously mirrors React state back to disk with save_onboarding_status_cmd. A one-second debounce prevents excessive writes, and an isCompletingRef guard blocks saves during the final completion routine.

Why is the permissions step limited to macOS?

The Permissions step renders only when currentStep === 4 and the host platform is macOS, because the required microphone, system-audio, and screen-recording entitlements are handled through macOS-specific Tauri APIs. Other platforms skip this stage entirely.

How does Meetily handle background model downloads during onboarding?

When the user reaches the Download Progress step, the context calls startBackgroundDownloads to fetch the Parakeet speech-recognition model and the chosen summarisation model in parallel. Tauri emits progress events that update parakeetProgress, summaryModelProgress, and their associated metadata objects in real time.

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 →