Skip to content

Toolset · Dart, Riverpod, single codebase

Flutter

  • Dart
  • Flutter
  • Riverpod

Flutter gives one codebase across iOS and Android. Our stack keeps state predictable, storage transactional, and secrets off the device filesystem — the failure modes that bite cross-platform apps hardest.

Where two tools compete, the one marked our default is what we reach for.

01

Build & dependencies

1 tool
pubour default

Dart's package manager and registry; dependencies declared in pubspec.yaml. Pin versions and audit transitive packages.

02

Dependency injection

1 tool

A service locator (get_it) plus optional codegen (injectable) for registration. Our default — simple and testable.

final getIt = GetIt.instance;

void setup() {
  getIt.registerLazySingleton<ApiClient>(() => ApiClient());
  getIt.registerFactory<UserRepository>(() => UserRepository(getIt()));
}

// use:  final repo = getIt<UserRepository>();
03

State management

2 tools
Riverpodour default

Compile-safe, testable state management without BuildContext coupling. Our default.

Event-driven, highly structured state management with strict separation of events and states — excellent for complex enterprise flows and large teams where business logic is heavily documented. The trade-off is verbosity and a steeper learning curve that can slow simpler features. Decision rule: start with Riverpod for its compile safety, testability, and simpler mental model; choose Bloc only for large teams or extremely complex business logic that benefits from its strict event-sourcing architecture.

04

Networking

2 tools
dioour default

HTTP client with interceptors, retries, cancellation, and multipart. Our default.

The minimal official client; fine for simple calls.

05

Push notifications

1 tool

One API over both FCM (Android) and APNs (iOS) — handle onMessage, onBackgroundMessage, and onResume, with the platform setup each side needs (google-services.json for Android, GoogleService-Info.plist for iOS). Route to the right screen on payload tap via GoRouter. Our default.

06

Local storage

2 tools
Driftour default

Reactive, type-safe SQLite with real transactions — avoid the load-mutate-store races that plague blob stores (see the local-first blueprint). Our default.

Fast key-value store; keep writes single-writer to avoid lost updates.

07

Security

3 tools

Our default wrapper over the platform secure stores — Android Keystore (API 23+) and iOS Keychain (kSecClassGenericPassword) — for tokens and secrets. On Android it uses EncryptedSharedPreferences (API 23+) and falls back to AES-encrypted SharedPreferences pre-API 23; that fallback is a known limitation any deployment targeting older APIs must plan around.

For application-level encryption beyond token storage — hashing, AES-GCM, and public-key operations in pure Dart. Reach for these when the app itself needs to encrypt data or verify signatures.

Pin the server's public-key hash via dio interceptors or http_certificate_pinning, and keep a fallback pin so certificate rotation doesn't lock users out.

08

Serialization & navigation

2 tools

Immutable models, unions, and JSON codegen. Our default for data classes.

Declarative, deep-link-friendly routing.

09

Testing

2 tools

Widget/unit tests with null-safe mocking. Our default.

First-party end-to-end tests on a real device/emulator.

10

Background work

2 tools
workmanagerour default

Periodic and one-off background tasks (sync, cleanup, analytics) mapped onto the platform schedulers — iOS background fetch and Android WorkManager, each with their own constraints. Our default.

Offload heavy work off the UI thread — use compute for a one-shot job or Isolate.spawn for a long-lived worker. Never block the main isolate.

11

Monitoring & observability

4 tools

Crash reporting for Flutter on iOS and Android; record Dart errors and native crashes together. Our default.

Crashes, performance, and error monitoring across Flutter with a single SDK and dashboard.

Automatic and custom performance traces — app start, network calls, and screen rendering.

Timeline, memory, and widget-inspector profiling in development.

12

CI/CD

4 tools
GitHub Actionsour default

CI for analyze / test / build; cache pub and the Flutter SDK. Our default CI.

Flutter-specialised CI/CD with signing and store publishing built in.

Store deployment automation for the iOS and Android outputs.

Beta builds to testers on both platforms.

13

Linting & formatting

3 tools

The built-in analyzer with the recommended lint set enabled. Our default.

dart formatour default

The official, zero-config formatter. Our default for formatting.

A stricter lint ruleset when you want more rigour.

Building on Flutter?

We ship production Flutterwith exactly this stack. Tell us what you're building.

Start a conversation