Skip to content
Public template

About

Production-ready Flutter template on Clean Architecture - configure it, don't rebuild it

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

753 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flutter Starter

A production-ready Flutter template on Clean Architecture that you configure, not rebuild.

Auth with token refresh, a pinned HTTP layer, secure storage, routing, localization, theming and three tiers of tests are already wired together and tested. Every external service sits behind a small contract with a no-op default, so pointing the app at your backend and providers takes configuration and an adapter, not a rewrite.

CI Release Flutter 3.47+ Android | iOS | Web | Desktop very_good_analysis MIT license

Use this template · Getting started · Documentation · Releases

The sign-in screen in light mode, offering the offline demo account The tasks sample listing incomplete and completed tasks in light mode Editing a task in dark mode The feature flags debug screen in dark mode

Captured on the iOS Simulator in light and dark mode, with no backend configured. The same code builds for Android, the web and desktop.

Why this starter

  • Runs before you have a backend. Until you set BASE_URL, a debug build signs in offline with a demo account, so the whole app works end to end on day one. Setting it turns the demo off.
  • No vendor lock-in. Storage, networking, error reporting, performance tracing and RASP each sit behind a contract with a no-op or local default, and the Crashlytics, Firebase Performance, freeRASP and GraphQL integrations ship as templates rather than dependencies (Contracts and adapter map).
  • Safe release builds. A staging or production build refuses to start on a development configuration, a BASE_URL that is not https, or certificate pinning with no fingerprints, instead of shipping quietly misconfigured.
  • Verified, not assumed. Every pull request runs format, analysis with very_good_analysis, the full test suite under a 94% line coverage floor, and checks that the docs' code, paths and commands still match the code (Quality gates).
  • Yours in a few commands. A Mason brick renames the package, app name and application ids, and one command removes the sample features (Using this template).

Quick start

flutter pub get                    # Flutter 3.47+ (Dart 3.13+)
./scripts/dev/setup_git_hooks.sh   # format and analyze on commit, Conventional Commits
flutter run                        # no BASE_URL yet: sign in with the demo account

pubspec.lock is resolved on the current stable Flutter. On an older 3.47+ SDK, flutter pub get rewrites a few SDK-pinned entries in it; that diff is your SDK's, not the project's, so do not commit it.

To point the app at your API, copy the example environment file, set BASE_URL in it, and pass it to the build:

cp .env.example .env
flutter run --dart-define-from-file=.env

.env is a build input, never a Flutter asset, so it does not ship inside the app. Without --dart-define-from-file, flutter run uses the built-in development defaults.

Generated code (Freezed, json_serializable, Riverpod) is committed; run flutter pub run build_runner build --delete-conflicting-outputs only after changing an annotated source. Details, platforms and troubleshooting: Getting started.

What you get

Area What is in place Docs
Architecture Domain, data and presentation layers per feature, Riverpod for state and dependency injection, contracts in lib/core/contracts with adapters alongside Architecture
Auth and session Sign-in and registration, token refresh with retry, session restore on launch, forced logout; tokens in the iOS Keychain / Android Keystore Auth repositories
Networking Dio behind a transport-agnostic client, the token sent only to the API's own origin, certificate pinning, an HTTP cache, redacted logs, and a WebSocket realtime client Security
Configuration .env layering, --dart-define and per-environment defaults; a release build checks its configuration at startup Configuration
Routing go_router with signed-in and signed-out guards and a not-found screen Routing
UI Material 3 design tokens with light and dark themes, accessibility helpers, and English, Spanish, Arabic (RTL) and Vietnamese Internationalization, Accessibility
Observability A logging service, plus error-reporting and performance seams with no-op defaults Performance
Tests Unit and widget tests mirroring lib/, acceptance goldens, and Patrol end-to-end tests Testing
Tooling Git hooks, CI, feature scaffolding, release scripts, fastlane lanes and deploy workflows Deployment
Sample: tasks A complete removable slice: local create, edit, complete and delete lib/features/tasks
Sample: feature flags A complete removable slice: compile-time and local flags with a debug screen lib/features/feature_flags

Tech stack

Layer Choice
Framework Flutter 3.47+, Dart 3.13+
State and DI Riverpod 3 with code generation
Navigation go_router 18
Networking Dio 5, web_socket_channel for realtime
Models Freezed 4, json_serializable
Storage flutter_secure_storage 11 for tokens, shared_preferences for the rest
Localization flutter_localizations and intl, ARB files
Testing flutter_test, mocktail, Patrol
Tooling very_good_analysis, Mason, fastlane, GitHub Actions

Project structure

lib/core/          the foundation: config, network, session, storage, routing, logging, security
lib/features/<f>/  one slice per feature: domain/, data/, presentation/, di/, routing/
lib/shared/        design system, theme, shared widgets
test/              unit and widget tests, mirroring lib/; acceptance goldens in test/acceptance/
integration_test/  Patrol end-to-end tests
scripts/, tool/    developer, CI and release scripts; docs and repository checks

Presentation and data depend on domain, and domain depends on neither. See Understanding the codebase.

Quality gates

Every pull request runs the Quality gate:

  • format, and flutter analyze with very_good_analysis;
  • the full test suite in random order, with a 94% total line coverage floor;
  • a check that flutter pub get and code generation leave the tree unchanged.

Pull requests that touch them also run the docs check (the docs' code samples, paths, symbols and commands must match the code), action pinning and workflow lint, an Android build on the JDK floor, and the git hook and release script tests. Patrol on an Android emulator, per-layer coverage and the store builds run manually or weekly, not per pull request. Run the same gate locally:

./scripts/dev/audit_template.sh

Documentation

Start with docs/README.md. The usual path:

  1. Getting started - setup, environments, running on each platform.
  2. Understanding the codebase and Architecture.
  3. Adding a feature - scaffold one with ./scripts/dev/create_feature.sh <name>.
  4. Testing, including the Patrol end-to-end tests (integration_test/README.md).
  5. Deployment - store builds and CI.

Contribution conventions (branches, commits, the quality gate) are in CONTRIBUTING.md.

Using this template

This section is for setting the project up from the template. Delete it once that is done, together with the parts above that describe the template rather than your app: the badges and links under the title, the screenshots, "Why this starter", and the Support section below.

  • Rename the package, display name and application ids: Fork and customize.
  • Brand it: put your logo at assets/images/logo.png and run ./scripts/dev/setup_branding.sh for launcher icons and splash screens.
  • Drop what you do not need. dart run tool/strip_sample_features.dart --apply removes both sample features; see tool/README.md for the variants.
  • Connect your backend by setting BASE_URL, which also turns the demo sign-in off (how to remove it). Requests go to BASE_URL + /v1, and sign-in expects the auth wire format; see Connecting your backend.
  • Keep up with the template: the upgrade guide records which release your copy came from and how to take in later ones.

The rename can also be done with Mason: dart pub global activate mason_cli, mason get, then mason make flutter_starter_setup (bricks/README.md). If you rename by hand instead, drop the bricks with dart run tool/strip_sample_features.dart --apply --keep-samples --remove-bricks, or add --remove-bricks to whichever strip you run.

Support

Bugs and questions go to GitHub issues; every release and its upgrade notes are on the Releases page. Report a vulnerability privately from the repository's Security tab, not in a public issue.

License

MIT - see LICENSE.

About

Production-ready Flutter template on Clean Architecture - configure it, don't rebuild it

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages