architecture-feature-first
Structures Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project structure, adding repositories/services/view models (or cubits/providers/notifiers), or wiring dependency injection. State management agnostic.
Best use case
architecture-feature-first is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Structures Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project structure, adding repositories/services/view models (or cubits/providers/notifiers), or wiring dependency injection. State management agnostic.
Structures Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project structure, adding repositories/services/view models (or cubits/providers/notifiers), or wiring dependency injection. State management agnostic.
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "architecture-feature-first" skill to help with this workflow task. Context: Structures Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project structure, adding repositories/services/view models (or cubits/providers/notifiers), or wiring dependency injection. State management agnostic.
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/architecture-feature-first/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How architecture-feature-first Compares
| Feature / Agent | architecture-feature-first | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Structures Flutter apps using layered architecture (UI / Logic / Data) with feature-first file organization. Use when creating new features, designing the project structure, adding repositories/services/view models (or cubits/providers/notifiers), or wiring dependency injection. State management agnostic.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Flutter Architecture — Feature-First Skill This skill defines how to design, structure, and implement Flutter applications using the recommended **layered architecture** with **feature-first** file organization. It is **state management agnostic**: the business logic holder in the UI layer may be named ViewModel, Controller, Cubit, Bloc, Provider, or Notifier — depending on the chosen state management approach. The architectural rules apply equally to all of them. ## When to Use Use this skill when: * Designing the folder/file structure of a new Flutter app or feature. * Creating a new View, ViewModel, Repository, or Service. * Deciding which layer owns a piece of logic. * Wiring dependency injection between components. * Adding a domain (logic) layer for complex business logic. --- ## 1. Layers Separate every app into a **UI Layer** and a **Data Layer**. Add a **Logic (Domain) Layer** between them only for complex apps. ``` ┌──────────────────────────────────────────────────────────────┐ │ UI Layer │ Views + business logic holders │ │ │ (ViewModel / Cubit / Controller / Provider) │ ├──────────────────────────────────────────────────────────────┤ │ Logic Layer │ Use Cases / Interactors (optional) │ ├──────────────────────────────────────────────────────────────┤ │ Data Layer │ Repositories + Services │ └──────────────────────────────────────────────────────────────┘ ``` **Rules:** - Only adjacent layers may communicate. The UI layer must never access a Service directly. - The Logic layer is added **only** when business logic is too complex for the business logic holder or is reused across multiple screens. - Data changes always happen in the Data layer (SSOT = Repository). No mutation in UI or Logic layers. - Follow unidirectional data flow: state flows **down** (Data → UI), events flow **up** (UI → Data). --- ## 2. Feature-First File Structure Organize code by **feature**, not by type. Group all layers belonging to one feature together in a single directory. Each feature directory contains the files needed for that feature, named according to the chosen state management approach: | Approach | Business logic holder file | |---|---| | MVVM / ChangeNotifier | `*_viewmodel.dart` / `*_controller.dart` | | BLoC | `*_cubit.dart` / `*_bloc.dart` | | Provider / Riverpod | `*_provider.dart` / `*_notifier.dart` | Example: an `auth` feature would have files like `auth_viewmodel.dart` (or `auth_cubit.dart`, `auth_provider.dart` depending on approach), `login_screen.dart`, and optionally `login_usecase.dart`. --- ## 3. Component Responsibilities ### View - Describes how to present data to the user; keep logic minimal and only UI-related. - Passes events to the business logic holder in response to user interactions. - Keep views focused on presentation; extract reusable widgets into separate components. - Use `StatelessWidget` when possible; keep build methods simple. ### Business Logic Holder (ViewModel / Cubit / Controller / Provider) - Contains logic to convert app data into UI state and maintains current state needed by the view. - Exposes callbacks (commands) to the View and retrieves/transforms data from repositories. - Business logic must not live in UI widgets; only interact with repositories via the business logic holder. ### Repository - Single Source of Truth (SSOT) for a given type of model data. - The only class allowed to mutate its data; all other classes read from it. - Handles business logic such as caching, error handling, and refreshing data. - Transforms raw data from services into domain models consumed by business logic holders. ### Service - Wraps API endpoints and exposes asynchronous response objects. - Isolates data-loading and holds no state. --- ## 4. Domain Layer (Use Cases) Introduce use cases/interactors **only** when: - Logic is complex or does not fit cleanly in the UI or Data layers. - Logic is reused across multiple business logic holders or merges data from multiple repositories. Do not add a domain layer for simple CRUD apps. --- ## 5. Dependency Injection Use dependency injection to provide components with their dependencies, enabling testability and flexibility. - Supply repositories to business logic holders via constructors. - Supply services to repositories via constructors. - Design all components with well-defined interfaces so implementations can be swapped without changing consumers. --- ## References - [Flutter app architecture guide](https://docs.flutter.dev/app-architecture/guide) - [Architecture case study (Compass app)](https://docs.flutter.dev/app-architecture/case-study) - [Architecture recommendations](https://docs.flutter.dev/app-architecture/recommendations)
Related Skills
flutter-app-architecture
Provides best practices for Flutter app architecture, including layered architecture, data flow, state management patterns, and extensibility guidelines.
testing
Writes and reviews Flutter/Dart tests. Use when writing unit tests, widget tests, or reviewing existing tests for correctness, structure, and naming conventions.
riverpod
Uses Riverpod for state management in Flutter/Dart. Use when setting up providers, combining requests, managing state disposal, passing arguments, performing side effects, testing providers, or applying Riverpod best practices.
provider
Uses the Provider package for dependency injection and state management in Flutter. Use when setting up providers, consuming state, optimizing rebuilds, using ProxyProvider, or migrating from deprecated providers.
patrol-e2e-testing
Generates and maintains end-to-end tests for Flutter apps using Patrol. Use when adding E2E coverage for new features, regression tests for UI bugs, or testing native interactions (permissions, system dialogs, deep links)
mocktail
Uses the Mocktail package for mocking in Flutter/Dart tests. Use when creating mocks, stubbing methods, verifying interactions, registering fallback values, or deciding between mocks, fakes, and real objects.
mockito
Uses the Mockito package for mocking in Flutter/Dart tests. Use when generating mocks, stubbing methods, verifying interactions, capturing arguments, or deciding between mocks, fakes, and real objects.
flutterfire-configure
Sets up Firebase for Flutter apps using FlutterFire CLI. Use when initializing a Firebase project, running flutterfire configure, initializing Firebase in main.dart, or configuring multiple app flavors.
flutter-errors
Diagnoses and fixes common Flutter errors. Use when encountering layout errors (RenderFlex overflow, unbounded constraints, RenderBox not laid out), scroll errors, or setState-during-build errors.
firebase-storage
Integrates Firebase Cloud Storage into Flutter apps. Use when setting up Storage, uploading or downloading files, managing metadata, handling errors, or applying security rules.
firebase-remote-config
Integrates Firebase Remote Config into Flutter apps. Use when setting up Remote Config, managing parameter defaults, fetching and activating values, implementing real-time updates, or handling throttling and testing.
firebase-messaging
Integrates Firebase Cloud Messaging (FCM) into Flutter apps. Use when setting up push notifications, handling foreground/background messages, managing permissions, working with FCM tokens, or configuring platform-specific notification behavior.