Skip to main content

Create your first app

smf create generates an app in a new directory. In a terminal it asks what it needs to know, and with the answers given as options it asks nothing.

Answer the questions​

Run smf create in the directory where the app's own directory should go:

smf create

This is what a run looks like when you keep the start screen home, which is selected already, and pick tabs at the bottom, a settings screen, the onboarding, the localization, the theme, get_it, the event bus, the app icon and the splash screen:

πŸ‘‹ Hello! Let's create a Flutter app with Say My Frame.
? App name my_app
? Organization (reverse domain) com.example
? Features: which do you want? home β€” Start screen with a welcome and the next steps
? Infrastructure: which do you want? none
? Layout: which module provides it? bottom_tabs β€” Tabs in a bar at the bottom of the app
? Settings screen: which module provides it? settings β€” Settings screen with the settings of the modules
? Onboarding screen: which module provides it? onboarding β€” Onboarding on the first launch of the app
? Localization: which module provides it? gen_l10n β€” Texts in ARB files with gen-l10n of Flutter
? Theme: which module provides it? material_theme β€” Light and dark Material 3 themes with a palette and a bundled font
? Push messages: which module provides it? None
? Notifications: which module provides it? None
? Dependency injection: which module provides it? get_it β€” Service locator with get_it
? State management: which module provides it? None
? Events: which module provides it? event_bus β€” Events between parts of the app with event_bus
? Authentication: which module provides it? None
? REST API: which module provides it? None
? Purchases: which module provides it? None
? Values in .env: which module provides it? None
? Crash reporting: which module provides it? none
? Analytics: which module provides it? none
? App icon: which module provides it? launcher_icons β€” App icon from assets/branding with flutter_launcher_icons
? Splash screen: which module provides it? native_splash β€” Light and dark splash screen from assets/branding with flutter_native_splash
? CI: which module provides it? None
βœ“ Checking the machine (5ms)
Adding flutter_core: the only provider of the app entry role, which every app needs.
Adding go_router: the only provider of the router role, which home requires.
Adding shared_preferences: the only provider of the preferences role, which onboarding requires.
βœ“ Rendering the app (0.2s)
βœ“ Getting the packages of the app (1.3s)
? Making the app icon from assets/branding (dart tool/update_app_icon.dart), for launcher_icons. Run it now? Yes
βœ“ Making the app icon from assets/branding (1.3s)
? Making the splash screen from assets/branding (dart run flutter_native_splash:create), for native_splash. Run it now? Yes
βœ“ Making the splash screen from assets/branding (1.3s)
βœ“ Cleaning up the imports (1.8s)
βœ“ Applying dart fix (0.8s)
βœ“ Formatting the code (0.2s)
βœ“ Getting the packages of the app in its directory (1.0s)
Created my_app in /Users/you/projects/my_app.
Run it:
cd /Users/you/projects/my_app
flutter run

A short note with links to the community follows.

The questions​

QuestionWhat the answer does
App nameThe default is my_app. The name becomes the Dart package name of the app in snake_case, so My App becomes my_app, and it names the app's directory.
OrganizationReverse domain notation, com.example by default. It starts the identifiers of the app: com.example.my_app on Android and com.example.my-app on iOS, where bundle identifiers take no underscores.
Features, InfrastructureThese list the modules that provide no role, grouped by their kind. Select any number of them, or none. home is selected already, so Enter takes it, and the app starts on it.
One question per roleEach lists the modules that provide the role, such as the layout, the onboarding screen or dependency injection. A role that an app has at most one of also offers None, and Enter takes its first module. For crash reporting and analytics you can select several modules, or none. The roles come in an order that goes from what the user of the app sees to what gets the app released.

A role may ask one more question once the modules are known. With the feature sign_in, or another module that brings the authentication, smf create asks who may use the app without an account: nobody, everyone, or everyone as an anonymous user. See Sign-in.

A role that the modules you picked require offers no None. When only one module provides it, SMF adds that module without asking and tells you why. Here the start screen requires a router, so SMF adds go_router. The layout, the settings screen and the onboarding screen require the router too, which is why SMF asks about them first. The onboarding, the theme and the localization require the preferences, which remember what the user chose. Only shared_preferences provides them, so SMF adds it without a question here. Push messages require the notifications, so the question of push messages comes before the one of the notifications.

Use the arrow keys to move, the space bar to select in a list that takes several answers, and Enter to confirm. Ctrl-C cancels the run at any question and leaves nothing behind.

What happens next​

After the questions, SMF renders the app in memory and writes it to a temporary directory. There it gets the packages with flutter pub get, runs the setup steps of the modules, cleans up the imports, applies dart fix and formats the code. Then it moves the app to its directory and gets the packages again, because Flutter writes the path of the app into some files. If flutter pub get or a step that the app cannot do without fails, the app stays in the temporary directory, and the error says where. A step that the app can do without, such as the tool that makes the app icon or the configuration of Firebase, is left for later with its command instead, and a failure of dart fix or dart format is only a warning.

Pass everything as options​

You can give every answer on the command line instead. This command generates the same app without asking anything:

smf create my_app --org com.example -m home,bottom_tabs,settings,onboarding,gen_l10n,material_theme,get_it,event_bus,launcher_icons,native_splash --no-input
  • -m lists the modules, separated by commas, in the order of the answers above. SMF adds what they need, such as the router for home.
  • --org sets the organization. Without it, the organization is com.example.
  • --no-input turns the questions off. A run that would have to ask stops with an error that names the option to add. Such a run takes only the modules that it was given, so home is in the list too.

A run without a terminal, as in a script or in CI, asks nothing either. See the smf create reference for every option.

Run the app​

cd my_app
flutter run

On its first launch, the app shows the onboarding: two pages, with Skip above them and Next below. Skip, or Get started on the last page, ends it, and the app opens on the start screen. That screen greets you, names the app and lists three next steps, the first of which is to replace it with a screen of your own. At the bottom are two tabs, Home and Settings. Under Settings, the user chooses the language, English or Ukrainian, and the theme mode, and the app remembers both. The next launch opens on the start screen right away.

flutter run builds the flavor dev, which installs as My App Dev under the id com.example.my_app.dev, next to the other two flavors. The icon and the splash screen show the mark of Say My Frame until you replace them.

A walk through an app with these screens and with local_notifications, recorded on an iPhone simulator. So its onboarding has three pages, with a page between the two of this app that asks to turn on notifications, and its settings screen has the row Notifications too. Its modules were chosen in another order, so its settings screen has Theme above Language.

An app with no screen to start on, such as an app without a feature, opens on the fallback start screen, which names the app and tells you where its first screen goes. With gen_l10n, such an app is in English and in Ukrainian too.

For iOS builds with Xcode 27 and Flutter 3.44, see troubleshooting.

Next​

  • Take a tour of the app to see what each module added.
  • To give the app sign-in, add sign_in and a state manager to -m, as in -m home,sign_in,bloc,bottom_tabs, and google_sign_in and apple_sign_in for sign-in with Google and Apple. Such an app signs in with Firebase Authentication, so it needs a Firebase project before it runs; see Sign-in.
  • To give the app notifications, add local_notifications, and firebase_messaging for push messages; see Notifications and push messages.
  • To make requests to your API, add dio, and fill in its address in .env; see REST API.
  • To run the checks on each push and build an APK on request, add github_actions; see CI.
  • To sell premium access, add paywall and a state manager, as in -m home,paywall,bloc,bottom_tabs. The app sells the plans of a RevenueCat project, and a debug build buys in the Test Store of RevenueCat once its API key is in .env; see Purchases.