UI/UX Part 25 — Onboarding, First Run & Permission Education UX Architecture

Reusable P2P Communication Platform

Status: UI/UX architecture specification
UI Series: Part 25
Desktop UI: Dioxus
Android UI: Kotlin + Jetpack Compose
Core runtime: Rust
Primary purpose: define the complete onboarding, first-run, account-entry, existing-device linking, recovery, profile setup, permission education, capability readiness, privacy defaults, skipped-step recovery, offline-first setup, accessibility, and Rust presentation architecture across desktop and Android.


1. Purpose

First-run UX determines whether users understand:

what the product is
whether they need an account
how identity works
how to link another device
how to recover an existing account
what permissions are actually needed
which permissions are optional
what still works if they decline

Poor onboarding often causes users to grant permissions they do not understand or abandon setup before reaching the useful product.

The governing principle is:

Ask for the minimum information and permissions required for the next meaningful task, and explain consequences before the operating system prompt appears.


2. Architectural Position

Rust Identity / Account / Capability Core
        │
        ├── account state
        ├── device state
        ├── recovery readiness
        ├── onboarding progress
        ├── required capabilities
        ├── optional capabilities
        └── feature readiness
        │
        ▼
Onboarding Presentation Service
        │
   ┌────┴─────┐
   │          │
Dioxus     Compose
Desktop    Android

Platform adapters own:

camera permission
microphone permission
notification permission
nearby/Bluetooth permission
location permission
OS credential/biometric
file picker
system settings navigation

Rust owns the semantic meaning of why a capability is needed.


3. Main First-Run Entry

Recommended first screen:

Welcome

[Create New Account]
[Use Existing Account]

Optional secondary:

Learn how this works

4. Avoid Immediate Permission Prompts

Do not launch first-run with:

notifications
camera
microphone
nearby devices
location

all at once.


5. Account Entry Modes

#![allow(unused)]
fn main() {
pub enum OnboardingEntryMode {
    CreateNewAccount,
    LinkExistingAccount,
    RecoverExistingAccount,
}
}

6. Create New Account

Purpose:

create new account identity
authorize current device
configure minimal profile

7. Link Existing Account

Purpose:

authorize this device from an already trusted device

Uses Part 12 device-link architecture.


8. Recover Existing Account

Purpose:

regain access using supported recovery material

Uses Parts 15/16.


9. Do Not Conflate Link and Recover

Hard rule.

Linking assumes:

at least one trusted device is available

Recovery assumes:

trusted device may be unavailable

10. First-Run State

#![allow(unused)]
fn main() {
pub enum FirstRunState {
    Uninitialized,
    ChoosingEntryMode,
    CreatingIdentity,
    LinkingDevice,
    Recovering,
    ConfiguringProfile,
    ReviewingPrivacy,
    CapabilitySetup,
    Ready,
}
}

11. Onboarding Progress

Progress should be semantic, not artificial percentage.

Example:

Account
Profile
Permissions
Ready

12. Avoid Long Wizard Feel

Prefer:

3–5 meaningful steps

with optional configuration deferred.


13. Create New Account Flow

Recommended:

Welcome
→ Create New Account
→ Identity created locally
→ Name/profile
→ Recovery recommendation
→ Optional permission setup
→ Home

14. Local-First Identity Creation

Should work without Internet where architecture allows.


15. Offline Creation UX

Example:

Account created on this device
You can start using nearby/local features now.

16. Server Registration

If some account service requires network later:

complete asynchronously

and clearly show pending status.


17. Profile Setup

Minimum:

Display name
Optional avatar

18. Display Name

Explain:

This is how people will recognize you.

19. Name Validation

Rust-owned.


20. Avatar

Optional.

Do not block onboarding.


21. Avatar Permissions

Use system picker.

No storage-wide permission.


22. Profile Skip

Allow:

Skip for now

where product can generate safe fallback.


23. Recovery Recommendation

After creating account:

Set Up Recovery

strongly recommended but not necessarily mandatory.


24. Recovery Setup

Links into Part 15.


25. Recovery Skip

If allowed:

Not now

but show honest consequence:

If you lose all trusted devices, you may not be able to recover your account.

26. Link Existing Account Flow

New device:

Use Existing Account
→ Link from Trusted Device
→ Scan QR / Enter Code
→ Authenticate
→ Existing device approves
→ Optional SAS
→ Device linked
→ Sync/setup
→ Home

27. Manual Link Fallback

Always available if QR/camera inaccessible:

Enter Link Code

28. Desktop Link Flow

Recommended:

Enter code
Paste code
Optional webcam scan

29. Android Link Flow

Recommended:

Scan QR
Enter code
NFC optional

30. Linking Consequence

Before approval:

This device will be able to access your account and receive messages.

31. New Device Name

After linking:

Name this device

optional.


32. Device Sync Setup

Show semantic phases:

Setting up account
Syncing conversations
Preparing search
Ready

33. Do Not Block on Derived Work

Search indexing/thumbnails can continue after Home is usable.


34. Recovery Flow

Recommended:

Use Existing Account
→ Recover Account
→ Choose Recovery Method
→ Verify Recovery Material
→ Create Fresh Device Identity
→ Restore Account Metadata
→ Optional Restore Backup
→ Home

35. Recovery Key Entry

Sensitive screen.

Part 15 rules apply.


36. Backup Restore Choice

If recoverable backup found:

Restore Message History
Skip for now

37. Account Recovery vs Data Restore

Explain:

Account access restored
Message history can be restored separately

if architecture distinguishes.


38. Permission Philosophy

Permissions should be requested:

just in time

when the user performs an action needing them.


39. Permission Education Layer

Before OS prompt, show:

what feature needs it
why
what data is accessed
whether optional
what works without it

40. Permission Model

#![allow(unused)]
fn main() {
pub struct PermissionEducationView {
    pub capability: AppCapability,
    pub title: String,
    pub reason: String,
    pub required_for: Vec<FeatureKind>,
    pub optional: bool,
    pub alternative: Option<CapabilityAlternative>,
}
}

41. App Capabilities

#![allow(unused)]
fn main() {
pub enum AppCapability {
    Notifications,
    Camera,
    Microphone,
    NearbyDevices,
    Location,
    Files,
    Biometric,
    ScreenCapture,
}
}

42. Android Notification Permission

Request when user meaningfully wants:

message alerts
incoming call alerts

43. Notification Education

Example:

Allow notifications to receive message and call alerts while the app is closed.

44. Notification Decline

App remains usable.


45. Notification Decline Consequence

Show:

You may miss alerts while the app is not open.

46. Camera Permission

Request when user chooses:

Scan QR
Take Photo
Video Call

not during generic onboarding.


47. Camera Alternative

For device linking:

Enter code manually

48. Microphone Permission

Request when user chooses:

Voice Note
Audio Call
Video Call

49. Microphone Decline

Text messaging still works.


50. Nearby Devices Permission

Request when user chooses:

Find Nearby
Offline Nearby Messaging

51. Nearby Education

Example:

Nearby access lets this app discover devices close to you for local communication.

52. Legacy Location Requirement

On Android versions where nearby scanning technically requires location-related permission:

explain accurately

without claiming precise location is shared if it is not.


53. Location Permission

Do not request for general nearby discovery unless platform requires it.

Use for:

SOS location
explicit location sharing

54. Location Education

Example:

Share your location with selected emergency contacts during an SOS.

55. Location Decline

SOS can still send without location.


56. File Access

Use:

system picker
SAF
native file dialog

rather than broad filesystem permission.


57. Biometric

Request only for:

app lock
high-risk reauthentication
recovery key access

58. Screen Capture Permission

Request when:

screen sharing

starts.


59. Permission Timing Rule

Never request a permission:

because the app may need it someday

60. Pre-Permission Screen

Structure:

Feature title
Why access is needed
What happens if denied
[Continue]
[Not Now]

61. OS Prompt

Appears only after user taps:

Continue

62. Denied Once

Offer alternative.


63. Permanently Denied / Don't Ask Again

Show:

Open Settings

64. Permission State

#![allow(unused)]
fn main() {
pub enum CapabilityPermissionState {
    NotRequested,
    Granted,
    Denied,
    BlockedBySystem,
    Unavailable,
}
}

65. Capability Readiness

#![allow(unused)]
fn main() {
pub struct CapabilityReadinessView {
    pub capability: AppCapability,
    pub state: CapabilityPermissionState,
    pub feature_ready: bool,
}
}

66. Permission Is Not Capability

Example:

camera permission granted

but:

camera hardware unavailable

So readiness considers both.


67. Desktop Permission UX

Desktop OS behavior varies.

The product should normalize:

camera
microphone
screen capture
notifications

where possible.


68. Desktop Permission Denial

Show system-specific action:

Open System Settings

if available.


69. No Fake Desktop Permission Prompt

If OS does not expose runtime prompt, do not simulate one as authority.


70. First-Run Privacy Defaults

Recommended conservative defaults:

read receipts: configurable
typing: configurable
presence: minimal
notification preview: sender-only or generic
unknown request privacy: strict
auto-download unknown requests: off

Exact defaults are product policy.


71. Privacy Review Step

Optional concise summary:

Presence
Read Receipts
Notification Previews

with:

Use Recommended Defaults
Customize

72. Avoid 20 Privacy Toggles During First Run

Detailed controls remain in Part 18 Settings.


73. Recommended Defaults Explanation

Use:

You can change these anytime.

74. Contact Import / Discovery

Do not force.


75. System Contacts Permission

If future feature supports contact matching:

request only when user chooses Find People From Contacts

76. Contact Import Privacy

Explain:

which contact data leaves device, if any

77. Default Recommendation

Do not upload address book by default.


78. First Useful Action

Onboarding should end with one useful next step.

Examples:

Add Contact
Link Another Device
Start Nearby
Open Chats

79. Ready Screen

Example:

You're ready
[Add Contact]
[Go to Chats]

80. Avoid Celebration Overload

A short completion state is enough.


81. Post-Onboarding Checklist

Optional home card:

Set up recovery
Enable notifications
Add an emergency contact
Link another device

82. Checklist Must Be Dismissible

Do not nag indefinitely.


83. Readiness Card

Use semantic states:

Complete
Optional
Needs Attention

84. Onboarding Skip

Allow skipping optional steps.


85. Resume Later

Skipped setup surfaces remain discoverable in:

Settings
Security Center
Devices
Emergency

86. Persisting Progress

Rust owns which durable onboarding tasks are complete.


87. UI Presentation Progress

UI can own:

current page
animation
temporary text field

88. Onboarding Progress Model

#![allow(unused)]
fn main() {
pub struct OnboardingProgressView {
    pub account_ready: bool,
    pub profile_ready: bool,
    pub recovery_ready: bool,
    pub notification_ready: bool,
    pub nearby_ready: bool,
    pub emergency_ready: bool,
}
}

89. Do Not Gate Home on Optional Readiness

Example:

notifications denied

must not block app.


90. Required Gates

Only truly required states can block:

no valid account identity
device authorization incomplete
critical storage initialization failure

91. Offline-First Onboarding

If Internet unavailable:

create account locally
configure profile
use nearby/local features

where backend permits.


92. Offline Existing-Device Link

Can use local QR/LAN/Bluetooth if backend supports.


93. Offline Recovery

Only if recovery material/backup is locally available.


94. Offline Status

Example:

No Internet
You can continue setup and use nearby features.

95. Do Not Block on Connectivity Unless Required

Hard rule.


96. Network-Required Step

If some external service required:

Internet is required for this step.

Offer:

Try Later

if optional.


97. Error Recovery

Onboarding errors should preserve user work.


98. Profile Save Failure

Keep entered name/avatar choice.


99. Device Link Failure

Offer:

Try Again
Enter Code
Use Recovery Instead

where appropriate.


100. Recovery Failure

Do not lose recovery input prematurely if safe to preserve temporarily.


101. Permission Failure

Offer alternate route.


102. Onboarding Crash

Resume from Rust durable state.


103. Process Death Android

Compose rebuilds from:

OnboardingSnapshot

not from assumed page sequence.


104. Desktop Restart

Same.


105. Idempotency

Creating identity/linking device must be command-idempotent.


106. Duplicate Button Tap

Cannot create multiple accounts/devices.


107. Back Navigation Android

Back should:

dismiss transient prompt
go to previous step

without destroying completed account state.


108. Cancel Create Account

Before identity committed:

safe cancel

After identity committed:

return to setup/home

not create another identity blindly.


109. Cancel Device Link

Cancels link session.


110. Cancel Recovery

Leaves current device unlinked/unrecovered.


111. Desktop Escape

Same semantic cancellation behavior.


112. Welcome Screen Accessibility

Screen reader:

Welcome
Create new account
Use existing account

113. Avoid Auto-Focus Trap

Focus first meaningful heading/action.


114. Keyboard Desktop

Entire onboarding can be completed using keyboard.


115. TalkBack Android

All first-run flows must be TalkBack-complete.


116. QR Accessibility

Manual code always present.


117. Recovery Accessibility

Recovery key input is grouped and pasteable.


118. Permission Accessibility

Education screen must explain:

permission name
feature
alternative

119. Large Text

Onboarding reflows vertically.

No fixed-height wizard cards.


120. RTL

All onboarding layouts mirror.

Codes/fingerprints remain canonical.


121. Reduced Motion

Step transitions can be instant/minimal fade.


122. Color Independence

Completion/warning states use:

icon
text

123. Cognitive Accessibility

Keep one primary decision per screen.


124. Avoid Jargon

Use:

Link this device

not:

authorize secondary endpoint

125. Explain Security Consequences

Example:

A linked device can access your account and receive messages.

126. Explain Recovery Consequences

Example:

Without recovery, losing all trusted devices may make your account unrecoverable.

127. Do Not Overteach Cryptography

Deep details remain optional.


128. Permission Education Copy Rule

Never claim:

We need this permission for security

unless true.


129. Permission Alternatives

Each optional permission should define fallback.


130. Permission Alternatives Matrix

Examples:

Camera denied → manual code
Microphone denied → text
Notifications denied → foreground use
Nearby denied → QR/manual/Internet
Location denied → SOS without location

131. Permission Request Frequency

Do not repeatedly nag after decline.


132. Re-Prompt Policy

Request again only when:

user retries feature
user opens related settings

133. System Settings Redirect

Use only when permission is blocked and user explicitly wants feature.


134. Notification Permission Re-Prompt

Avoid repeated startup banner.

Use readiness/settings card.


135. Onboarding Analytics

Do not collect sensitive recovery/security material.


136. Safe Metrics

Possible:

step completion
permission denial rate
time-to-first-message
setup failure class

without identity/content.


137. Do Not Profile Users by Accessibility/Privacy Choice


138. Crash Reports

Redact:

invite codes
recovery keys
QR payloads
contact identifiers

139. Onboarding Presentation Snapshot

#![allow(unused)]
fn main() {
pub struct OnboardingSnapshot {
    pub state: FirstRunState,
    pub entry_options: Vec<OnboardingEntryMode>,
    pub progress: OnboardingProgressView,
    pub capabilities: Vec<CapabilityReadinessView>,
    pub recovery: RecoveryStatus,
}
}

140. Onboarding Presentation API

#![allow(unused)]
fn main() {
pub trait OnboardingPresentation {
    async fn snapshot(
        &self,
    ) -> Result<OnboardingSnapshot, UiError>;

    async fn choose_entry(
        &self,
        mode: OnboardingEntryMode,
    ) -> Result<OnboardingSnapshot, UiError>;

    async fn create_account(
        &self,
        command: CreateAccountCommand,
    ) -> Result<OnboardingSnapshot, UiError>;

    async fn update_profile(
        &self,
        update: ProfileSetupCommand,
    ) -> Result<OnboardingSnapshot, UiError>;

    async fn complete(
        &self,
    ) -> Result<OnboardingResultView, UiError>;
}
}

141. Capability Education API

#![allow(unused)]
fn main() {
pub trait CapabilityEducationPresentation {
    async fn education(
        &self,
        capability: AppCapability,
    ) -> Result<PermissionEducationView, UiError>;

    async fn record_platform_result(
        &self,
        capability: AppCapability,
        result: PlatformPermissionResult,
    ) -> Result<CapabilityReadinessView, UiError>;
}
}

142. Device Link Handoff

Onboarding calls Part 12 API.

Do not duplicate device-link protocol in onboarding module.


143. Recovery Handoff

Uses Part 15/16 API.


144. Permission Platform Effect

Example:

#![allow(unused)]
fn main() {
pub enum OnboardingPlatformEffect {
    RequestNotificationPermission,
    RequestCameraPermission,
    RequestMicrophonePermission,
    RequestNearbyPermission,
    RequestLocationPermission,
    OpenSystemSettings(AppCapability),
    OpenFilePicker,
    OpenQrScanner,
}
}

145. Android ViewModel

Owns:

step navigation
permission effects
temporary profile fields
animation
OS prompt timing

Rust owns account/readiness truth.


146. Dioxus Presenter

Owns:

step routing
webcam/manual-code UI
native settings/file effects
focus

147. Capability Events

#![allow(unused)]
fn main() {
pub enum CapabilityUiEvent {
    CapabilityChanged(CapabilityReadinessView),
    PermissionPolicyChanged(AppCapability),
}
}

148. Onboarding Events

#![allow(unused)]
fn main() {
pub enum OnboardingUiEvent {
    StateChanged(FirstRunState),
    ProgressChanged(OnboardingProgressView),
    Ready,
}
}

149. App Entry Gate

At startup:

if account/device ready
    → normal shell
else
    → onboarding

150. Returning User

No onboarding replay unless account/device state requires it.


151. Revoked Device

Routes to:

Link Again
Recover Account

not generic first-run create account unless user chooses.


152. Partially Completed Setup

Resume semantic state.


153. Migration from Older App Version

Do not force onboarding again for mere schema migration.


154. Feature Education After Onboarding

Use contextual education.

Examples:

first voice note
first nearby search
first SOS
first backup

155. Do Not Frontload All Feature Tutorials

Hard rule.


156. Coach Marks

Use sparingly.

Never obscure core UI or trap assistive tech.


157. Feature Education Pattern

user invokes feature
→ short explanation
→ permission if needed
→ feature starts

158. Calls First Use

Start call
→ microphone/camera education
→ OS permission
→ call

159. Nearby First Use

Find Nearby
→ nearby education
→ OS permission
→ scan

160. SOS First Use

Prefer setup/test flow before real emergency use, but real SOS must not become blocked by lengthy tutorial.


161. Emergency Permission Readiness

Settings can preconfigure:

notifications
location
nearby

without forcing all during general onboarding.


162. Backup First Use

Explain:

where backup is stored
how it is protected
what recovery key means

at first backup, not app first launch.


163. Security Center First Use

Can show concise explanation of devices/recovery.


164. Plugin First Use

Plugin permission education belongs to Part 19.


165. Permission Copy Consistency

The same capability should use the same core explanation across onboarding/settings/feature prompt.


166. Capability Registry

Recommended central semantic registry.

#![allow(unused)]
fn main() {
pub struct CapabilityDescriptor {
    pub capability: AppCapability,
    pub purpose: CapabilityPurpose,
    pub optional: bool,
    pub fallback: Option<CapabilityAlternative>,
}
}

167. One Source of Truth for Permission Meaning

Avoid separate wording/semantics implemented independently by:

Compose screen
Dioxus dialog
Settings screen
Feature screen

168. Platform Copy Adaptation

Natural wording can differ while meaning stays same.


169. Readiness Diagnostics

Part 20 can inspect capability readiness.


170. Settings Integration

Part 18 exposes all permission/capability statuses after onboarding.


171. Security Integration

Part 15 handles recovery/device security.


172. Device Linking Integration

Part 12 handles trust/bootstrap.


173. Backup Integration

Part 16 handles data restore.


174. Accessibility Integration

Part 21 is mandatory.


175. Design System Integration

Part 22 provides onboarding components/tokens.


176. Responsive Integration

Part 23 adapts wizard/list/detail presentation.


177. Error-State Integration

Part 24 handles permission/network/setup failures.


178. Desktop Layout

Wide:

centered onboarding panel
optional explanatory side panel

179. Desktop Compact

Single focused panel.


180. Android Phone Layout

Full-screen step flow.


181. Android Tablet/Foldable

Can use:

step list/illustration
+
current form

if it improves clarity.


182. No Decorative Dependence

Illustrations are optional.

Core meaning in text/actions.


183. Progress Indicator Accessibility

Screen reader:

Step 2 of 4, Profile

if using step count.


184. Skip Link

Optional step has visible:

Skip for now

not hidden tiny text.


185. Back Link

Preserves completed secure state.


186. Account Creation Success

Do not immediately hide recovery recommendation.


187. Account Creation Failure

If identity was not committed:

retry safely

If committed:

resume setup

188. Link Session Expiry

Show:

Link code expired
Create/scan a new code

189. Recovery Wrong Key

Could not unlock recovery

not cryptographic details.


190. Unsupported Backup Version

Route:

Update App

191. Permission Unavailable

Example:

This device has no NFC

Hide/disable feature gracefully.


192. Capability Readiness Screen

Optional post-onboarding:

Notifications: Ready
Nearby: Not enabled
Microphone: Ask when needed
Recovery: Not configured

193. Recommended Readiness Policy

Do not label optional missing permissions as:

Setup incomplete

unless a user-selected feature depends on them.


194. Completion Criteria

Account/device ready is enough for onboarding completion.


195. Welcome Back

Returning after recovery/link can show:

Device ready

then enter home.


196. Testing Matrix

Required:

new account online
new account offline
link existing device
manual-code link
recovery
skip recovery
notification denied
camera denied
microphone denied
nearby denied
location denied

197. Android Tests

Verify:

runtime permission prompt timing
Don't Ask Again/system blocked
process death
rotation
TalkBack
large text
RTL

198. Desktop Tests

Verify:

keyboard-only
manual code
optional webcam
system notification/camera/mic settings
restart/resume

199. Offline Tests

Verify:

local account creation
local profile setup
nearby/device link if supported
deferred network registration

200. Security Tests

Verify:

duplicate create command
duplicate link approval
expired link
wrong SAS
wrong recovery key
revoked device

201. Permission Tests

No permission requested before contextual education.


202. Accessibility Tests

Complete first run:

without camera
with TalkBack
keyboard-only
200% text
RTL

203. Analytics Privacy Tests

No recovery key/invite code/profile secret in telemetry.


204. Resume Tests

Crash/restart at each semantic onboarding state.


205. Capability Consistency Tests

Same permission meaning/fallback appears in onboarding/settings/feature prompt.


206. Initial Production Scope

Ship:

Create New Account
Use Existing Account
Link Existing Device
Recover Existing Account
minimal profile setup
recovery recommendation
contextual permission education
notification/camera/microphone/nearby/location handling
manual-code alternatives
offline-first setup
resume after process death
post-onboarding readiness card

Defer:

long guided tours
social contact import by default
mandatory profile completion
bulk permission prompts
gamified setup completion

207. Definition of Done

UI/UX Part 25 is complete when:

  • first-run clearly distinguishes create, link, and recover
  • linking delegates to Part 12 and recovery delegates to Parts 15/16
  • account/device security truth remains Rust-owned
  • only truly required state blocks entry to the main app
  • optional profile/recovery/permissions can be deferred where safe
  • permissions are requested just in time after contextual education
  • every optional permission has an explicit fallback where possible
  • Android notification/camera/mic/nearby/location flows are defined
  • desktop camera/mic/notification equivalents are normalized without fake authority prompts
  • offline-first account creation/setup works where backend permits
  • no-Internet state does not block local setup unnecessarily
  • process death/restart resumes semantic onboarding state
  • permission denial never causes nag loops
  • post-onboarding readiness surfaces skipped configuration without blocking product use
  • accessibility, keyboard, TalkBack, large text, RTL, reduced motion, and QR/manual-code alternatives are explicit
  • Rust onboarding/capability/readiness APIs and events are specified
  • duplicate command, recovery, permission, offline, resume, and accessibility test matrices are included

208. Final Architecture

                        FIRST RUN
                            │
          ┌─────────────────┼─────────────────┐
          │                 │                 │
       Create              Link            Recover
          │                 │                 │
     New Identity      Trusted Device     Recovery Proof
          │                 │                 │
          └─────────────────┼─────────────────┘
                            │
                      Device Ready
                            │
                       Minimal Profile
                            │
                 Optional Capability Setup
                            │
                            ▼
                           Home

Permission path:

User chooses feature
        │
        ▼
Explain why permission is needed
        │
        ▼
User chooses Continue
        │
        ▼
OS permission prompt
        │
   ┌────┴─────┐
   │          │
Granted     Denied
   │          │
Feature    Fallback / Settings

209. Final Principle

Onboarding should get users to a working, secure product quickly without front-loading every permission and configuration decision.

The correct model is:

minimal secure setup
+
clear create/link/recover paths
+
contextual permission education
+
offline-first progress
+
optional setup deferred

not:

welcome
→ ask for every permission
→ long tutorial
→ force every setting
→ finally show the product

This gives Dioxus desktop and Android Compose a first-run experience that is privacy-conscious, resilient, accessible, and consistent with the shared Rust security model.