Open-source project
rmanguinho/clean-flutter-app avatar
rmanguinho/clean-flutter-app

clean-flutter-app is a TDD and Clean Architecture reference app for Flutter

Aplicativo feito em Flutter usando TDD, Clean Architecture, Design Patterns e SOLID principles

588 stars167 forksDartLicense varies

At a glance

What is it?
The clean-flutter-app repository is a small polls application for programmers, built as the companion code for a Flutter course, and it exists to demonstrate test driven development, Clean Architecture layering, SOLID principles and a long list of design patterns. It suits a developer learning how those ideas fit together in Dart, and it is not a starting point for a product.
Who is it for?
Adopt clean-flutter-app as a learning artefact if you are a Flutter developer who has written features but not yet structured a project around use cases, repositories and dependency injection, because the layering is laid out plainly and the accompanying course explains the reasoning.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 44 days ago.
What is it written in?
Mainly Dart, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A course companion, not a product

clean-flutter-app is a Flutter application built with TDD, Clean Architecture, design patterns and SOLID principles, and it is the companion code for a training course by Rodrigo Manguinho, known as Mango, published on Udemy. The application itself is a polls app for programmers, and the documentation for the API is hosted separately. That framing matters for how you should read the code, because the artefact is pedagogical. Every choice is meant to be legible, and the list of principles the project names reads like the syllabus of the course. The full set is the five SOLID principles, Single Responsibility, Open Closed, Liskov Substitution, Interface Segregation and Dependency Inversion, plus Separation of Concerns, Don't Repeat Yourself, You Aren't Gonna Need It, Keep It Simple Silly, Command Query Responsibility Segregation, Composition Over Inheritance, and Small Commits. That enumeration is the project's real content, and the application is the vehicle. The badges in the documentation place it in a specific generation of the toolchain, with Dart 2.14.2 and Flutter 2.5.1, and a null safety badge marked as done, which is the era when Dart's null safety migration was the interesting thing to demonstrate.

The patterns list is a catalogue of what the code demonstrates

The design patterns the project names are the second half of the syllabus. They are Factory, Adapter, Composite, Decorator, Dependency Injection, Abstract Server, Composition Root, Builder, Singleton, Observer and Strategy, plus AAA, Arrange Act Assert, as a testing convention. Several of these are load bearing in a Flutter codebase and several are there to make a point. Dependency Injection and Composition Root are the pair that does the architectural work, since a composition root is where the concrete implementations get wired into the abstract ones and the injection is how the tree is assembled. Adapter is the usual answer to a third-party API that does not match your domain, and it is a pattern a polls app has an excuse to demonstrate because it talks to an HTTP backend. Factory, Builder and Singleton cover object creation, which is the part of an architecture a beginner most often gets wrong by scattering constructors across the tree. Observer and Strategy cover behaviour that varies at runtime, and AAA is the shape every test in the repository follows. Nothing here is exotic, and that is the point. The patterns are the ones a working application actually needs.

Methodologies: TDD, BDD, reactive programming and GitFlow

The methodologies and designs the project lists are the third group. TDD is named first and is the organising method of the course, with BDD alongside it, then Clean Architecture, Reactive Programming, GitFlow, Modular Design, Dependency Diagrams and Use Cases. Reactive programming in a Flutter context usually means streams, and the Dart features list confirms that Streams sit alongside Futures, Async Await, and Stateless and Stateful Widgets. Use Cases and Dependency Diagrams are the two entries that belong to the architecture rather than to the toolchain, since a use case is the unit that the domain layer exposes to the presentation layer and a dependency diagram is the artefact that shows the direction of the arrows. GitFlow is a branching model rather than an architecture, and it is a plausible inclusion for a course that also teaches small commits as a principle. The mixing of architecture, method and tool in one list is a little untidy, but it maps the course syllabus rather than a formal taxonomy, and reading it as a reading list rather than a specification is the fair interpretation.

The library set, including two competing state approaches

The libraries and tools list is where a Flutter reference project becomes a real dependency discussion. Provider and GetX both appear, which is an unusual and useful pairing because they are competing approaches to state management, and a course that uses one of them while naming the other is implicitly making a point about the trade-off. Equatable is there for value comparison, Mockito and Mocktail are the two mocking libraries, again deliberately paired, and Faker, Meta, and Image Test Utils and Network Image Mock are test support packages. Flutter Secure Storage and LocalStorage are both named for persistence, and the i18n entry points at localisation, which is a common source of late rework in applications that ship in more than one language. Http covers the network layer and Flutter Version Management is the tool for pinning the SDK. Meta is worth pausing on, since it is the annotation package rather than a plain library, and it is what lets a codebase attach metadata to a class and read it back at runtime, which is the mechanism most often used to register a dependency in the composition root without a handwritten container.

The four test layers the project expects you to write

The test features list is the most actionable part of the documentation for a developer who wants to know what the course is trying to produce. It names unit tests, widget tests, stream tests, integration tests, test coverage, and the test doubles: mocks, stubs and spies. Naming all three double categories separately is a deliberate teaching choice, since the difference between a mock that asserts and a stub that returns and a spy that observes is exactly the kind of thing that gets hand-waved in a written tutorial. A widget test is what proves a Flutter widget renders a given state, a stream test is what proves a reactive pipeline emits the right values, and an integration test is what proves several layers work together. The repository layout supports that pairing. There is a lib/ directory for the application code and a separate test/ directory beside it, and the test folder is where the assertion of behaviour lives, which is the structural commitment of test driven development rather than a slogan about it. The .fvm/ directory at the top level is the Flutter Version Management configuration, and that is how the pinned SDK version is kept in the repository rather than on a developer's machine.

Reading the repository as a layered sample

The top level entries describe the project without describing the layers, and that is where you have to bring your own knowledge of what Clean Architecture looks like in Flutter. The listing is .fvm/, .gitignore, .metadata, README.md, android/, ios/, lib/, pubspec.lock, pubspec.yaml, requirements/, run_instruction.md and test/. The android/ and ios/ directories are the generated platform shells, which for a course project means the interesting code is entirely in lib/ and test/, and the requirements/ directory holds the assets for the course requirements, which is where the course logo and the screens referenced from the documentation live. pubspec.yaml and pubspec.lock are the Dart package manifest and its lock file, and the .metadata file is the Flutter tool's own record of the project type. There is a run_instruction.md at the top level, and it is the one file in the repository that tells you how to get the thing running on a machine, so it is the first thing to open. The absence of a services/ or data/ listing at the top level is not evidence that the layers are missing, only that they are organised inside lib/, where the Clean Architecture split of domain, data and presentation usually lives.

What the licence field and the badge disagree about

There is a licence ambiguity worth flagging before you copy code from this project. The documentation carries a GPLv3 licence badge at the top of the file, and the project page for the repository records the licence as unknown, meaning no licence file is declared where GitHub would show one. The top level listing does not include a LICENSE file, which is consistent with the unknown value. That matters because a course repository that shows a permissive-looking badge is not the same as a repository with a licence file you can read and comply with. The GPLv3 badge is a claim about intent, and the absence of the file means the terms are not in the repository for you to check. This is not legal advice, and the practical advice is narrow. If you intend to reuse code rather than read it for study, ask the author for the licence text or check the terms that came with the course. Reading a repository to understand how someone structured a Flutter application is a different act from copying its files, and only the second one needs a licence grant. The project also has a Ko-fi link for contributions, and the site is at rmanguinho.github.io.

Editorial conclusion

Adopt clean-flutter-app as a learning artefact if you are a Flutter developer who has written features but not yet structured a project around use cases, repositories and dependency injection, because the layering is laid out plainly and the accompanying course explains the reasoning. Do not adopt it as the base of a product, since it exists to illustrate a course, its licence field is recorded as unknown even though the project carries a GPLv3 badge, and it pins an older Flutter and Dart generation. Verify two things before you read it closely: that the pinned toolchain, Dart 2.14.2 and Flutter 2.5.1, still matches what you run, since the null safety badge and the version badges describe that generation, and that the layering you copy matches the layering in your own project, because the Clean Architecture arrangement is one of several defensible ones. The practical first step is to read the run instructions in the repository and the API documentation the project links, then work through the test/ directory alongside the lib/ directory, since the pairing is the point.

Frequently asked questions

What is clean-flutter-app?

It is a Flutter polls application for programmers built with TDD, Clean Architecture, design patterns and SOLID principles, published as the companion code for a Flutter training course by Rodrigo Manguinho on Udemy.

Which design patterns does clean-flutter-app demonstrate?

The project names Factory, Adapter, Composite, Decorator, Dependency Injection, Abstract Server, Composition Root, Builder, Singleton, Observer and Strategy, plus AAA, Arrange Act Assert, as a testing convention.

Which test types does clean-flutter-app expect?

The documentation lists unit tests, widget tests, stream tests, integration tests, test coverage, and the test doubles, mocks, stubs and spies. The repository pairs a lib/ directory with a separate test/ directory, which is the structural commitment behind the TDD method.

What Flutter and Dart versions does clean-flutter-app target?

The badges in the documentation show Dart 2.14.2 and Flutter 2.5.1, with null safety marked as done, and the repository carries a .fvm/ directory for Flutter Version Management, which is how the SDK version is pinned in the project.

Which state management and mocking libraries does clean-flutter-app use?

The library list names Provider and GetX for state management, Equatable for value comparison, Mockito and Mocktail for mocking, and Faker, Meta, Image Test Utils and Network Image Mock as test support, alongside Http, Flutter Secure Storage, LocalStorage and i18n.

What licence is clean-flutter-app under?

The documentation carries a GPLv3 badge, but the repository's licence field is recorded as unknown and no licence file appears in the top level listing, so the terms are not in the repository to read. Ask the author before reusing the code rather than only reading it.

Official sources

  1. Issues
  2. Project website
  3. README
  4. rmanguinho/clean-flutter-app on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rmanguinho-clean-flutter-app.svg)](https://hysenlabs.com/projects/rmanguinho-clean-flutter-app)

Was this useful?