Cross-Platform Mobile App Development with Flutter

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
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.

Showing 1 of 1 servicesAll 1735 services
Cross-Platform Mobile App Development with Flutter
Complex
from 2 weeks to 3 months
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Cross-Platform Mobile App Development with Flutter

Flutter 3.x based on Dart compiles code directly into native ARM bytecode through AOT compilation — no JavaScript bridge, no WebView. This is a fundamental difference from React Native, where any native API call passes through an asynchronous bridge. In practice, the difference is noticeable where animation, custom rendering, and gesture handling matter: Flutter renders each frame through its own Skia engine (or Impeller with Flutter 3.10+), not relying on platform's native widgets.

If a project requires 60/120fps on Flutter 3.16+ with Impeller on iOS, a separate conversation with the team is unavoidable: Impeller is enabled by default on iOS, on Android — via the --enable-impeller flag. Where the old Skia managed fine, Impeller may behave differently on the first shader compilation.

Where Flutter wins and where caution is needed

A cross-platform approach is justified when UI logic is identical on iOS and Android, and the product is needed quickly. Flutter covers 80–90% of needs through standard Material and Cupertino widgets. Problems begin at the edges.

Platform-specific APIs. Bluetooth Low Energy — through flutter_blue_plus, but its behavior on Android 12+ (when Google changed permissions from ACCESS_FINE_LOCATION to BLUETOOTH_SCAN) requires separate handling. On iOS — a separate NSBluetoothAlwaysUsageDescription key in Info.plist plus background mode bluetooth-central. Omit it — App Store rejects by guideline 5.1.1.

Background execution. Dart Isolates don't solve OS-level background task problems. For background geolocation — background_locator_2 + WorkManager on Android (via workmanager package). On iOS — CLLocationManager with allowsBackgroundLocationUpdates. Flutter provides only a thin wrapper here; the real logic is native.

Platform channels. When a ready-made plugin doesn't exist, we write MethodChannel or EventChannel. Typical case — integration with a POS terminal via manufacturer SDK (Ingenico, PAX): SDK available only as .aar for Android and .framework for iOS, wrapped in native code, passed through a channel. Here «cross-platform» ends exactly at the channel boundary.

How we build architecture

For projects with 5+ screens, we use clean architecture with separation into data, domain, presentation layers. State management — Riverpod 2.x (providers like AsyncNotifierProvider instead of deprecated ChangeNotifierProvider). BLoC applied where the team is already experienced with it or strict event-driven flow with state testability is required.

Navigation — go_router 13.x with deep linking and web-routing support (if Flutter Web is needed in the project). Old Navigator 1.0 avoided — on complex nested routes, the stack breaks unpredictably.

DI — via get_it + injectable. Code generation via build_runner reduces boilerplate but requires discipline: freezed for immutable models, json_serializable for serialization, drift or isar for local DB. isar in 3.x shows noticeably faster hive on collection operations — in one project with 200k records the difference was ~3x on filtering.

Real example. A taxi aggregator app — three user roles (passenger, driver, dispatcher), real-time updates via WebSocket (web_socket_channel), maps via flutter_map + OpenStreetMap tiles (client didn't want to pay for Google Maps SDK). Background geolocation updates — via WorkManager on Android and BGAppRefreshTask on iOS with Dart wrapper. Release build — Fastlane + GitHub Actions: one workflow builds --release APK and IPA in parallel, signs, uploads to Firebase App Distribution for QA.

Testing and CI

Dart unit tests — standard flutter_test. Integration tests — integration_test package (run on real device or emulator via flutter drive). Widget tests cover key components: testWidgets with WidgetTester and pump/pumpAndSettle.

In CI (GitHub Actions / GitLab CI) we separate: flutter analyze + dart format --set-exit-if-changed on each PR, tests — in parallel on Android API 33 emulator and iOS Simulator. Builds for TestFlight and Google Play Internal Track — via Fastlane Match for certificates.

Performance profiled in flutter run --profile + DevTools: Timeline view shows jank frames (>16ms), Memory view — heap between rebuilds. Typical issues: excessive setState calls in deep trees, unoptimized images (decode without cacheWidth/cacheHeight), expensive computations in build() instead of moved to compute().

What impacts timelines

Project scope Approximate timeline
MVP, 5–10 screens, REST API 6–10 weeks
Mid-size product, 15–30 screens, offline mode 3–6 months
Complex product: real-time, payments, maps, BLE 6–12 months

Cost calculated individually after analyzing requirements — technical specification, mockups, integration description.

Typical mistakes in independent development

We see three problems most often when auditing Flutter projects from other teams.

Wrong provider architecture. ChangeNotifier with global state that rebuilds entire screen on any change. Transition to Riverpod with granular select-s solves the problem but requires refactoring.

Platform channel without error handling. Native code throws exception → channel crashes → app crashes without clear message. All MethodChannel calls wrapped in try/catch PlatformException.

Ignoring isolates for heavy operations. Deserializing 10MB response on main isolate gives noticeable freeze. compute() or manual Isolate.spawn — mandatory for data >1MB.