Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
What Changed in Flutter 3 and Dart 3: Impeller, Patterns, Widget Previews, material_ui and What's Next
Dart 3.0 made null safety mandatory and brought records, patterns and sealed classes; 3.6 to 3.13 took small steps that change everyday code, from digit separators to primary constructors. On the Flutter side there are Impeller, SwiftPM, UIScene, Widget Previews and, between 3.44 and 3.50, Material moving into the material_ui package; we show with real output that the language version comes from the pubspec, and how to upgrade.
Publishing a Flutter App: Google Play and the App Store, Signing, Versioning, Flavors and CI
A Flutter app takes the same road in both stores: release build, signing, a test channel, review and a gradual release. For Bookstore we cover version numbers, environments with --dart-define-from-file (and why they cannot carry secrets), the Android upload key and Play App Signing, iOS signing and TestFlight, the 2026 store rules and a signed App Bundle build in GitHub Actions.
Testing in Flutter: Unit, Widget and Integration Tests, Fake Repositories and Golden Tests
The backbone of Flutter testing is unit and widget tests written with fake repositories; mocks only for "was this call made?", integration_test for critical flows and golden tests for catching visual changes on a single platform. With Bookstore's 86 tests, a checkout flow through provider and go_router, mocktail's registerFallbackValue trap and the platform differences of goldens.
Local Storage and Offline in Flutter: shared_preferences, flutter_secure_storage, SQLite/drift and Caching Strategy
In Flutter, small non-secret settings go to shared_preferences, tokens to flutter_secure_storage (iOS Keychain, Android Keystore) and data you query to SQLite through drift. We move Bookstore's cart to drift, try a migration and a reactive query, and show the catalog without internet in the order fresh cache, network, stale cache, all without changing the ViewModels.
API Integration in Flutter: http/dio, JSON Serialization, Repositories and Connecting to the ASP.NET Core Bookstore API
The solid way to connect a Flutter app to an ASP.NET Core API is to keep HTTP in one ApiClient (timeout, retry only for GET, a single refresh on 401), to turn JSON into the domain model in one place and to swap the repository without touching the ViewModel. With real responses from a SQLite copy of the Bookstore API, ProblemDetails mapping, and the 10.0.2.2, cleartext and CORS traps.
Navigation in Flutter: Navigator, Declarative Routing with go_router, Deep Links and Auth Guards with redirect
In go_router, context.go goes to a URL and rebuilds the stack from the URL's hierarchy, while context.push adds to the current stack and can return a result. With real test and Chromium output we add to Bookstore a bottom navigation where each tab keeps its own stack with StatefulShellRoute, the /catalog/books/:isbn deep link, a redirect auth guard that reruns by itself through refreshListenable, and PopScope to keep a form from being lost.
State Management in Flutter: From setState to ChangeNotifier, DI with provider and the Official Architecture Guide
Flutter's official architecture guide recommends View, ViewModel, Repository and Service layers for app state, unidirectional data flow, and dependency injection with provider. We build Bookstore's cart with a ChangeNotifier-based CartViewModel, Commands and a sealed Result, show with real test output how Selector cuts an unneeded rebuild on a price change, and compare the approach with Riverpod, Bloc and signals.
Forms and User Input in Flutter: Form, TextFormField, Validation, Focus and the Keyboard
In Flutter a form is held together by Form and a GlobalKey<FormState>; a field is valid when its validator returns null, and the server's ProblemDetails errors are written to the matching field with forceErrorText. Using the sign-in and delivery address forms, we show with real test output how to choose an AutovalidateMode, focus the first invalid field with FocusNode, where input formatters stop, how the body shrinks when the keyboard opens, and the Angular Reactive Forms counterparts.
Theming and Material 3 in Flutter: ThemeData, ColorScheme, Dark Mode, the material_ui Package and Cupertino
ColorScheme.fromSeed does not use the seed color as is; it generates separate light and dark palettes with readable contrast, and values with no slot in ColorScheme are added to the theme with ThemeExtension. With real test output we cover Bookstore's brown theme, dark mode, our own color tokens, the move to material_ui/cupertino_ui as the SDK's Material is deprecated in 3.50, adaptive widgets, and the Turkish locale with intl formatting.
Lists and Grids in Flutter: ListView.builder, Slivers, Lazy Rendering and the Bookstore Catalog Screen
The default ListView constructor also builds only the visible rows, but it creates every row widget up front; data-driven lists are built with ListView.builder or slivers, while shrinkWrap makes all thousand rows build. We build Bookstore's catalog screen with CustomScrollView, SliverAppBar and a list/grid switch, and show with real test output paged loading, pull-to-refresh, empty and error states, and cacheWidth cutting a cover's memory from 8 MB to 122 KB.
Flutter Layout: Constraints Go Down, Sizes Go Up — Row, Column, Expanded, Stack and Overflow Errors
In Flutter a parent gives its child a constraint, the child picks its own size within it, and the parent sets the position; a Text in a Row overflows because it gets an unbounded width. We print constraints in a test and show with real output tight versus loose constraints, Expanded and Flexible, the three classic layout errors, and a book details screen with phone and tablet layouts built on LayoutBuilder.
Everything Is a Widget in Flutter: StatelessWidget, StatefulWidget, BuildContext and the Three Trees
In Flutter a widget is not the thing on the screen but an immutable configuration: on a rebuild widgets are replaced while elements and render objects stay, and State lives in the element. Using BookCard and FavoriteButton, we show with real test output the State lifecycle with its Angular counterparts, how const cuts off rebuilds, the mounted check after an await, and how state slides to the wrong row without keys.