Dynamic Themes for Mobile Apps

Why users abandon apps due to theme issues Users expect the app to adapt to their preferences: dark theme in the subway, accent color matching the phone wallpaper, at least two modes. If theme switching has a delay or flash, the user leaves. We've seen projects where implementing themes took 3 mo

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Why users abandon apps due to theme issues

Users expect the app to adapt to their preferences: dark theme in the subway, accent color matching the phone wallpaper, at least two modes. If theme switching has a delay or flash, the user leaves. We've seen projects where implementing themes took 3 months and resulted in 5 buggy screens. Over 10 years we've developed an architecture that works on all platforms and doesn't tolerate mistakes. One common problem is the flash of wrong theme: on first launch, the screen flashes light theme, then switches to the saved dark theme. This happens if the theme is read asynchronously. On iOS it's solved by synchronous reading of UserDefaults in AppDelegate, on Android via SplashScreen API. Proper implementation eliminates this effect and retains the user.

Contact us for an estimate of your project — we will analyze your current architecture and propose the optimal solution.

Architecture of the theme system

The key decision is how to store the current theme and how to pass it to components.

iOS (SwiftUI)

We use @Environment + custom EnvironmentKey. Create AppTheme as ObservableObject, publish via environmentObject, all components read via @EnvironmentObject var theme: AppTheme. When theme.colorScheme changes, SwiftUI automatically redraws the entire tree. Switching is instant, without UIApplication.shared.windows hacks.

iOS (UIKit)

More complex: UIAppearance proxy for global settings + traitCollection override. Or a custom ThemeManager via Notification Center: on theme change, all subscribed components call applyTheme(). Downside: need to explicitly unsubscribe, easy to get retain cycles.

Android (Compose)

MaterialTheme(colorScheme = currentColorScheme) in the root of composition. CompositionLocalProvider(LocalAppTheme provides theme). When remember { mutableStateOf(lightColorScheme) } changes, Compose re-composes only the subtrees that read the theme. Very efficient.

React Native

ThemeContext via React Context API + useContext. Or a ready-made solution via styled-components/native with ThemeProvider. On theme change, all components subscribed to the context re-render. To prevent unnecessary renders: React.memo + useMemo for the theme object.

Flutter

MaterialApp(theme: lightTheme, darkTheme: darkTheme, themeMode: themeMode). Custom themes — ThemeExtension<T>. ThemeMode.system / .light / .dark managed via setState or Provider/Riverpod.

How to ensure theme persistence without restart?

The chosen theme needs to be saved. iOS: UserDefaults + @AppStorage in SwiftUI. Android: DataStore<Preferences> (recommended over SharedPreferences). React Native: AsyncStorage or MMKV for synchronous access. Flutter: SharedPreferences or Hive.

Critical point: on first launch, the theme must be applied before the user sees the first frame. Otherwise there will be a flash of wrong theme — the screen flashes from the default theme to the saved one. On iOS it's solved by synchronous reading from UserDefaults in AppDelegate / @main before the window is drawn. On Android — via SplashScreen API with the correct background color. We guarantee the absence of this effect.

How to avoid memory leaks when switching themes?

With active theme switching, it's easy to create many subscriptions and listeners that are not cleaned up. On iOS we use Combine with AnyCancellable and store(in: &cancellables), on Android — Flow with collect in lifecycleScope. We test on 10+ devices, checking for leaks via Instruments and Android Profiler. The savings on debugging can be significant — preventing bugs early pays off the investment.

How to implement dynamic themes: step-by-step plan

  1. Audit the current UI: identify all places where colors, fonts, icons are used. Determine which components need adaptation.
  2. Design the palette: define a set of colors (primary, secondary, background, surface, error) for light and dark schemes. If a custom accent is needed, plan generation from a seed color.
  3. Choose the storage mechanism: based on the platform, select persistent storage (UserDefaults, DataStore, AsyncStorage, SharedPreferences). Ensure reading happens synchronously before the first frame renders.
  4. Implement on the platform: integrate the theme system according to best practices (Environment, Context, ThemeProvider). Write tests to verify correct theme switching without flashing.
  5. Test on 10+ devices: check on different OS versions, with different settings (System theme, accessibility). Use Instruments / Android Profiler for memory leaks.

How to test theme switching?

Test that reveals most issues: open a screen with complex UI → switch theme 5–10 times quickly → ensure no flash, no memory leaks (Instruments / Android Profiler), and all colors are applied correctly. Special attention: UIAlertController, UIActivityViewController, system components on iOS — they don't always react to custom themes and require separate handling.

Testing checklist for dynamic themes:

  • Check switching light/dark theme on the main screen and all child screens.
  • Switch theme rapidly 10 times in a row — no memory leaks, no flickering.
  • Ensure system components (ActionSheet, ShareSheet) use the correct theme.
  • Verify theme persistence after app restart.
  • Test with Material You (Android 12+) — should pick up colors from wallpapers.
  • On iOS — check with Dark Mode active in the system and without.

Custom accent color

Android 12+ supports Material You — a dynamic palette is generated from the user's wallpaper via DynamicColors.applyToActivitiesIfAvailable(this). Result: the app automatically adapts colors to the phone's personalization. Palette generation takes less than 5 ms, which is 10 times faster than custom color processing.

For a custom color picker inside the app: you need to generate a full ColorScheme from the selected seed color. On Android this is dynamicDarkColorScheme / dynamicLightColorScheme (API 31+) or the material-color-utilities library for API <31. On iOS — manual calculation of derived colors via HSL.

Common mistakes when implementing themes

Mistake Consequence Solution
Asynchronous theme reading Flash of wrong theme Synchronous reading before first frame
Ignoring system theme No automatic switching Use ThemeMode.system
Hardcoding colors Difficult maintenance Externalize all colors into a palette
No testing on tablets Uneven color changes Add to checklist

What's included in dynamic theme development?

  • Analysis of current app architecture
  • Design of the theme system (palette, storage and propagation methods)
  • Implementation on the chosen stack (iOS/Android/Flutter/RN) following best practices
  • Integration of theme saving and restoration
  • Testing on 10+ physical devices and emulators
  • Documentation for maintenance and further development
  • 30 days of free support after delivery
Scope of work Duration
Only dark/light switching 1–2 days
Multiple predefined themes 2–3 days
Dynamic accent color 3–5 days
Material You (Android) + full system 4–6 days

Developing dynamic themes is an investment that quickly pays off through increased user retention. Order dynamic theme implementation — and we'll ensure a seamless transition. Get 30 days of free support and consultations. Our team has 10+ years of experience in mobile development and Apple and Google certifications.

Additional information: Human Interface Guidelines — official Apple recommendations for working with color.