Upgrade to Pro — share decks privately, control downloads, hide ads and more …

1 App, 2 Platforms, Millions of Users - Flutter...

Avatar for Jonathan Filbert Jonathan Filbert
August 30, 2025
3

1 App, 2 Platforms, Millions of Users - Flutter in Gopay App @ DevFest Jakarta

My presentation for Google DevFest Jakarta

Avatar for Jonathan Filbert

Jonathan Filbert

August 30, 2025
Tweet

Transcript

  1. 1 App, 2 Platforms, Millions of Users: Adopting Flutter in

    Building GoPay Flutter Jonathan Filbert | @jonathanfilbert Software Engineer, GoTo Financials
  2. Call me Jofil! 👋 Crowdfunding @ Chipin Job-Matching @ MyRobin

    Crypto @ Pintu Fintech @ Tokopedia Fintech @ GoPay Co-Founded GarudaHacks Co-Started GDSC Universitas Indonesia Co-Founded RISTEK Open Source Top 1% Mentor ADPList IEEE Conference Best-Speaker
  3. GoPay in numbers: 2.2% of ID’s GDP GOTO’s Contribution, LPEM

    FEB UI research 2023 Used by 71% of ID Insight Asia research, 2022 Processed Rp360 Trillion GOTO Financial GTV - GOTO Annual Report, 2022
  4. To match the scale of growth, we aim to be

    robust, productive, and scalable. Flutter
  5. Start with Monorepo, do it well. Unlike its big brother,

    GoPay is built in Monorepo. We focus on our North Star: Productivity and Robust. Separate folders / pods by team-led ownerships: - GoPay consumer Flutter app - Shared packages - Pod-owned folder - Pod-owned feature package Early days: Agree on conventions, architectures (e.g. state management) Melos to orchestrate. Fvm to standardize. GoPay Flutter App Shared infrastructures: - routes package - networking package - analytics package etc etc Pod A feature A package feature B package ... Pod B feature A package feature B package ... Pod C feature A package feature B package ...
  6. Hot Reload increases productivity With hot reload, productivity increases by

    33%, debugging small - medium - large devices at once effortlessly.
  7. Coming from the Web and more mature frameworks / libraries,

    a lot of code convention standards are set in the community. E.g. with Redux, you will always have 1 store and a root reducer in your main app. For each feature, 1 reducer and action. What about Flutter? BLOC vs Cubit vs Providers? Reusing blocs? Listeners? Scalable Code Conventions Redux official docs.
  8. Things can go a bit out of hand… 😅 Flutter’s

    nested & declarative paradigm sometimes hinder teams from adopting.. Enter the Services - View - Widgets architecture 🤜 Meme comic, Toggl
  9. As with a map, you should establish a set of

    expectations about where to find parts of the project, and in which order these parts fit together. Flutter ~ MIT Communication Lab
  10. Services - Views - Widgets Modular Architecture Caption Services -

    cubit_a/ - cubit_b/ - listeners/ - listener_a/ - listener_b/ - home_listeners.dart - providers/ - home_providers.dart - home_services.dart Views: - home_view.dart - shared/ - widgets/ - utils/ - user_banner - widgets/ - user_banner_view.dart - user_banner.dart home_page.dart pubspec.yaml readme.md Services - Hub of business logic Views - Controlling widgets, event-aware entities Widgets - Pure UI components With this architecture, we have a scalable and predictable folder structure with clear ownerships.
  11. 1. Services - Hub for all business logic In GoPay,

    a page can house multiple business logics and API calls, utilizing reusable Cubits, we can easily “plug-and-play” business logics from features.
  12. 2. Views - Bridge between Logic and UI A view

    translates business logic into rendered UI. It parses data from Cubits, processes it, and controls the rendered UI. The goal here is to ensure the UI does not concern about logics, adhering to separation of concerns.
  13. Presentational UI components that do not depend on any 3rd

    party dependencies (e.g. Service Locators), do not concern the rendering context, and are driven by constructor props. Their only concern should be to render what’s given from the View above. A button widget should not implement any external services, should not care where it is rendered, and should behave only according to the given props. 3. Widgets - Pure UI components