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

> Discover Meetily's four-step first-time user onboarding flow: Welcome, Setup, Downloads, and Permissions. Learn how React context and Tauri manage the state effectively.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-19

---

**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/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)](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)](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)](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.

### Navigation API

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:

```tsx
// 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>
  );
}

```

### Navigating Steps with goNext

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

```tsx
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:

```tsx
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/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:

```tsx
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`](https://github.com/Zackriya-Solutions/meetily/blob/main/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.