BowlerKit
Features

Settings

1/22/2026

Comprehensive guide to the Settings system in the Expo application.

The Settings system in the Expo application is designed to be highly customizable, modular, and user-friendly. It leverages Zustand for state management and AsyncStorage for local persistence, while maintaining synchronization with the backend server for a consistent cross-device experience.

Architecture Overview

The settings system is built on a modular architecture where each category is a dedicated route and state is managed through a combination of Zustand stores and React Context.

  • State Management:
    • General & Notifications: Managed by usePreferencesStore (Zustand).
    • Appearance: Managed by ThemeProvider (React Context) for real-time UI updates.
    • Security: Managed by various hooks and useSecurityStore.
  • Persistence: Preferences are saved locally using AsyncStorage (via a custom service wrapper in @/services/storage).
  • Synchronization: Automatically synchronizes local settings with the backend API when the user is authenticated.
  • UI Components: Built using custom UI components and Design Tokens (defined in @/constants/design-tokens) for consistent styling across light and dark modes.
  • Localization: Fully integrated with react-i18next for multi-language support.

Settings Categories

1. General Settings

Managed by app/settings/general.tsx and usePreferencesStore.

FeatureDescription
Language & RegionUsers can change the app language (e.g., ID, EN) and region.
Time ZoneAutomatically or manually set the application time zone.
Privacy ControlToggles for usage data sharing and personalized experience recommendations.
Data SyncAutomatic synchronization of preferences with the server.

2. Appearance Settings

Managed by app/settings/appearance.tsx and useTheme.

This section provides deep visual customization options:

  • Theme Mode: Switch between Light, Dark, or System (follows device settings).
  • Theme Styles: Choose from predefined visual styles: Modern, Retro, Cozy, or Paper.
  • Accent Colors: Personalize the primary application colors (Green, Blue, Indigo, Purple, Pink, Amber).
  • Accessibility:
    • Reduce Motion: Option to limit animations for a more stable experience.
    • Theme-aware Tokens: UI automatically adjusts colors and spacing based on the selected theme style.

3. Notification Settings

Managed by app/settings/notifications.tsx and usePreferencesStore.

GroupOptions
Push NotificationsMaster toggle for enabling/disabling all push alerts.
MarketingOptional alerts for promotions and special offers.
Updates & TipsToggle for receiving health tips and application updates.

4. Security Settings

Managed by app/settings/security.tsx and security-related hooks.

Comprehensive account protection and management:

  • Authentication:
    • Change Password: Dedicated screen for secure password updates.
    • Biometric Login: Support for Face ID / Fingerprint authentication.
    • Two-Factor Auth (2FA): Toggle for enhanced account protection.
  • Session Management:
    • Active Sessions: View all devices currently logged into the account.
    • Revoke Sessions: Ability to log out specific devices or all devices remotely.
  • Login History: A detailed log of successful and failed login attempts with IP addresses.
  • Danger Zone: A secure process for permanent account deletion.

Technical Implementation

Accessing Preferences (Zustand)

To access or observe settings in your components, use the usePreferencesStore hook or its specific selector hooks:

import { usePreferencesStore, useLanguage } from '@/store/preferences-store';

const MyComponent = () => {
    // Select specific values for performance
    const language = useLanguage();
    const { setLanguage } = usePreferencesStore();

    return (
        <Button onPress={() => setLanguage('en')}>
            Change to English
        </Button>
    );
};

Accessing Theme (Context)

Theme properties like colors and tokens are accessed via the useTheme hook:

import { useTheme } from '@/constants/theme-context';

const StyledView = () => {
    const { tokens, brightness } = useTheme();

    return (
        <View style={{ backgroundColor: tokens.accentSurface }}>
            <Text style={{ color: tokens.onSurface }}>
                Themed Text
            </Text>
        </View>
    );
};

Help Center

The Help Center is accessible via the Settings menu but is treated as a separate feature module. It includes:

  • Frequently Asked Questions (FAQ)
  • Contact Support
  • Feedback Submission
  • App Version Information

For more details, refer to the Help Center Documentation.

Best Practices for Developers

  1. Zustand for State: Use individual selector hooks from preferences-store.ts to avoid unnecessary re-renders.
  2. Theme Consistency: Always use tokens from useTheme() instead of hardcoded hex colors.
  3. Async Initialization: Ensure initialize() is called from the store during app startup to load persisted settings.
  4. Backend Sync: When adding new settings, ensure they are added to the UpdatePreferencesData type and synced in the store's action.
  5. Localization: Always wrap text in the t() function from useTranslation() and add keys to locales/.