2026-08-11 · 9 min read
The CRAFT Framework: A Practical Model for Flutter Architecture Decisions
CRAFT is a reasoning framework for Flutter architecture decisions — Constraints, Responsibility, Adaptability, Fitness, and Tradeoffs. Learn how to use it to make and defend real architecture choices.
Most of us Flutter developers don't struggle with architecture because we don't know the patterns. We struggle because nobody taught us how to choose between patterns when the "correct" answer depends on context that changes from app to app.
You can memorise Clean Architecture, MVVM, and the Repository pattern and still freeze the first time a senior engineer asks: "Why did you structure it this way?"
That question isn't really about code. It's about reasoning. And reasoning is exactly what most architecture content skips over in favour of diagrams.
CRAFT is a framework built to close that gap as a way of thinking through any architectural decision, regardless of which pattern you land on. It stands for Constraints, Responsibility, Adaptability, Fitness, and Tradeoffs.
CRAFT is not a replacement for Clean Architecture, MVVM, or any pattern you already use. It's the reasoning layer underneath all of them; the questions you should be asking before you pick one.
Here's how each piece works, and how to actually use it.
C — Constraints
Every architecture decision starts with limits, not preferences. Before you choose a state management approach or a folder structure, you need to know what you're actually working within: team size, timeline, existing infrastructure, device targets, offline requirements, the client's technical maturity.
A five-person startup shipping an MVP in six weeks and a twelve-engineer team maintaining a five-year-old banking app are not solving the same problem, even if both are "Flutter apps." Architecture that ignores constraints isn't good architecture; it's a solution looking for a problem.
Before opening your IDE, write down the three hardest constraints on the project. If you can't name them, you're not ready to architect anything yet.
R — Responsibility
This is where most Flutter codebases quietly rot: unclear ownership. A widget that fetches data, transforms it, and renders it is doing three jobs, and when something breaks, you don't know which of the three failed.
Responsibility means every layer, class, and function has one reason to exist and one reason to change. It's the underlying principle beneath every "why do we need a repository layer" question. The repository isn't there because a tutorial said so. It's there so your UI layer's only responsibility is UI, and your data layer's only responsibility is data.
// Violates single responsibility — fetching, transforming, and rendering
class UserProfileScreen extends StatelessWidget {
Future<Widget> buildProfile() async {
final response = await http.get(Uri.parse('/api/user'));
final user = User.fromJson(jsonDecode(response.body));
return Text('${user.firstName} ${user.lastName}');
}
}
// Each layer owns one job
class UserRepository {
Future<User> getUser() async { /* fetch + parse only */ }
}
class UserProfileViewModel extends ChangeNotifier {
Future<void> loadUser() async { /* orchestrate state only */ }
}
For any class you write, finish the sentence "this class is responsible for ___." If you need "and," split it.
A — Adaptability
Architecture isn't judged by how well it works today. It's judged by how much it costs you to change six months from now. Adaptability is designing for the change you can reasonably predict, without over-engineering for change that will never come.
This is the tension point most junior-to-mid engineers get wrong in both directions: either they hardcode everything and the app becomes unchangeable, or they abstract everything "just in case" and the app becomes unreadable. Adaptability means abstracting at the seams that are actually likely to move (a payment provider, a backend, an auth method), not at every seam that theoretically could.
Ask what's likely to change in the next 12 months, not what's theoretically possible to change. Architect for the former.
F — Fitness
Fitness is architecture's version of "does the shoe actually fit." A pattern that's celebrated in a conference talk can be wrong for your app if it doesn't fit your team's skill level, your app's complexity, or your users' actual needs.
Clean Architecture is a good example. It's genuinely valuable for large, long-lived, multi-team codebases. Applied to a three-screen utility app, it's ceremony; more folders than features, more abstraction than the problem justifies. Fitness means asking whether a pattern solves your problem, not whether it's respected.
There is no universally correct pattern. MVC is fine for small projects. MVVM handles most production apps well. Clean Architecture earns its complexity when the scale genuinely demands it. The mistake is not choosing the wrong pattern; it is not choosing deliberately.
T — Tradeoffs
There is no free architecture decision. Every choice you make gains you something and costs you something else, and the job of an architect isn't to find the option with no downside; it's to know exactly what downside you're accepting and why.
Choosing Riverpod over Provider is a tradeoff. Choosing to build your own backend over using Firebase is a tradeoff. Choosing offline-first is a tradeoff. Pretending otherwise is how teams end up defending decisions they can't actually explain.
For every major decision, write one sentence naming what you gave up. If you can't name it, you haven't actually evaluated the decision, you've just followed a trend.
Why This Matters More Than the Pattern Itself
The gap between a mobile developer and a mobile architect isn't knowing more patterns. It's being able to walk into an unfamiliar codebase, unfamiliar constraints, and unfamiliar team, and reason from first principles instead of reaching for whatever pattern is currently popular.
If you can walk through Constraints, Responsibility, Adaptability, Fitness, and Tradeoffs for a decision and explain each one out loud, you're not guessing anymore. You're architecting.
Written by Mobterest Studio — a mobile engineering brand helping developers and founders build better mobile products through architecture-first thinking. Follow along on YouTube for video breakdowns of the concepts covered here.
Want to go deeper?
Free and paid courses, async mentorship, and a beginner's path — everything Mobterest teaches, in one place.
Explore Engineering Residency →