Flutter Starter App

At this point I’ve probably created 8-10 Flutter apps. The setup is the same each time so I created a starter app that I can quickly modify to get something up and running fast.

If you’d like to use it, you can clone this repro: https://github.com/pmmucsd/flutter_base_app

Here’s the basic structure:

The architecture is primarily built off of stacked, an architecture developed and revised by the FilledStacks community. This architecture was initially a version of MVVM which they’ve modified as they’ve built large production applications. Essentially all the display code lives in views and all the business logic lives in viewmodels which are tied to views in a reactive way so that as data changes, widgets that rely on the data are notified and updated. Services are the other main component of this architecture. They are basically functions that will be used in many different viewmodels (database, api, location, local storage, etc..).

These are all dependencies on third party libraries:

Let’s go through each of the folders/files one by one to explain what they do and how you might use this starter app.

/assets

Assets Structure

This is where you place any assets that will be shipped with the app. In my apps I generally have fonts, images, and animations. If you want to add more folders you also have to update pubspec.yaml to add the folders to the spec.


/lib/app

App structure

The app folder holds the main configuration file for the app (app.dart). This file sets up the app, it’s routes, the logger and registers all the viewmodels, and services as dependencies.

Every time you add a new view, viewmodel or service you need update this file and run the following command in the terminal under project directory.

flutter pub run build_runner build --delete-conflicting-outputs 

This will update the following generated files: app.locator.dart, app.router.dart, app.logger.dart.


/lib/constants

Constants structure

Here I put all my constants:


/lib/models

Models Structure

In application_models.dart I put all the models the app will use (sometimes I break this up into files for each model. The models are useful/necessary when you want to save data or send it somewhere via an API. Each model defines a toJson and fromJson function to easily serialize into JSON strings and deserialize into models.

enums.dart are for simple enums


/lib/services

services structure

Services are functions that are used across many viewmodels. They are registered in app.dart as singletons (only one instance exists) and using the locator, a viewmodel can grab the singleton and use to perform its specified function. Common services I create are

I also use stacked_services for navigation and dialogs.


/lib/utils

Utils!! The worst directory to have because you stuff a bunch of random shit into it – but sometimes there isn’t another good place. I put ui_helpers.dart here which just contains a bunch of simple UI functions to remove the boilerplate in widgets.


/lib/views

views structure

For each screen in your app you’ll want to create a view and a viewmodel. The display code goes into the view which is built with a pointer to the corresponding viewmodel. When you need to perform logic, you call a function in the viewmodel which has access to all the services and data models you need. You can tell the view that the viewmodel is busy so that it can show progress indicators or not show certain widgets.

In some cases you have several custom widgets that compose the view and need access to the same view model. Stacked has a way to build several widget with a common viewmodel, so I’d review their docs if you find yourself in this situation.

Once you’ve created a view you’ll need to update app.dart with a route to that view and a registration of the viewmodel for that view.

I also created simple baseview and baseview_model files to make it easier to create new views.


/lib/widgets

Here is where you create custom widgets that will be used in the view. Widgets can have viewmodels too. I usually create a folder for each widget with a widget and a widgetviewmodel.


/lib/main.dart

This is the entry point for your app. For the most part you shouldn’t need to do much here but sometimes you need to set up a service before the app is run or you need to edit the MaterialApp widget that contains the rest of your code.

For the most part, that’s it! I would read the Stacked docs and maybe read/watch some of the FilledStacks tutorials (which are really great) so that you have a better understanding of the architecture before really diving in.