flutter-clean-architecture-tdd
Skill1 starsChanged 27 days agoBSD-3-ClauseView on GitHub
Builds a Flutter feature test-first across its domain, data and presentation packages, one failing test at a time. Use when implementing, planning or reviewing a Flutter feature with TDD, or checking that each layer has tests. Also use when moving a Flutter app's local storage off Hive with tests first.
In this repository52 other files it gives its agents.
- academic-research-assistantSkill
- answer-sheetSkill
- app-graphicsSkill
- app-landing-pageSkill
- app-screenshotsSkill
- break-uiSkill
- consumer-app-from-behaviorSkill
- cross-language-safetySkill
- dart-tool-scriptsSkill
- decision-sweepSkill
- engineering-diarySkill
- figma-review-loopSkill
- flutter-app-size-auditSkill
- flutter-async-at-the-edgeSkill
- flutter-async-cubit-safetySkill
- flutter-bloc-clean-architectureSkill
- flutter-cubit-smart-cachingSkill
- flutter-error-logging-conventionsSkill
- flutter-observability-instrumentationSkill
- flutter-paywall-and-review-timingSkill
- flutter-precommit-cleanupSkill
- flutter-router-decisionSkill
- flutter-runtime-safetySkill
- flutter-shorebird-otaSkill
- flutter-stream-architectureSkill
- flutter-strict-analysisSkill
- flutter-web-first-paintSkill
- forced-pivot-15-daySkill
- gplay-consoleSkill
- ios-distribution-feature-flagsSkill
- launch-readinessSkill
- launch-watchSkill
- locale-expert-reviewSkill
- market-pulseSkill
- mobile-ui-referenceSkill
- moscow-prioritizationSkill
- orchestrate-agentic-engineeringSkill
- parallel-agent-inboxSkill
- paywall-conversion-flowSkill
- paywall-transparencySkill
- proactive-crash-repair-loopSkill
- promise-auditSkill
- pr-preview-shippingSkill
- ship-first-dollar-appSkill
- slim-ios-simulator-fleetSkill
- spec-sql-harnessSkill
- store-launch-mastermindSkill
- sync-contextSkill
- task-blitzSkill
- techdebtSkill
- vendor-decisionSkill
- web-interface-reviewSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. About 0 are common, 17 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈17
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 11
Write each behavior's failing test before its code, starting in the domain package and moving outward.
- Distinctive: line 19
Before scaffolding a new app or feature, confirm these decisions, or state the choice the codebase already makes and ask whether to follow …
- Distinctive: line 25
Do not silently pick a default for greenfield work.
- Very specific: line 29
Read the workspace root pubspec.yaml, the feature's packages, their tests, and the app's router and dependency wiring.
- Distinctive: line 31
Write failing tests in the domain package first, then data, then presentation, then the app wiring.
- Distinctive: line 32
Run each new test before writing its code and confirm it fails for the reason the behavior is missing.
- Distinctive: line 34
Write the least code that makes each test pass.
- Distinctive: line 35
Do not edit a test's assertion to make it pass.
- Distinctive: line 38
Run format, code generation, analysis and every package's tests before calling the work done.
- Very specific: line 45
Keep fixtures in the test/fixtures/ folder of the package that reads them.
- Distinctive: line 47
Keep cubits to orchestration and state transitions, with no serialization, caching or network code.
- Very specific: line 53
If any pubspec.yaml depends on hive, hive_flutter, hive_ce or hive_ce_flutter, tell the human the project should migrate its local storage …
- Distinctive: line 54
Do not add new Hive boxes, adapters or type IDs, even when the human defers the migration.
- Distinctive: line 56
When the human agrees, migrate with tests first:
- Very specific: line 58
Add drift, drift_flutter and path_provider, plus drift_dev and build_runner as dev dependencies, in the package that owns local storage.
- Distinctive: line 61
Keep the local data source interfaces unchanged, so repository and cubit tests keep passing while only the data source implementation …
- Distinctive: line 62
Write a one-time importer that runs on first launch after the update.
- Distinctive: line 64
Test the importer against Hive fixtures, including empty boxes, corrupt entries, and a second run that must do nothing.
- Distinctive: line 65
Delete the Hive boxes from disk only after the import succeeded.
- Distinctive: line 66
Remove the Hive dependencies, adapters and generated code once the importer has shipped for at least one release.
- Distinctive: line 75
No DTO or generated type appears in a domain API, a cubit state or a widget.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Flutter Clean Architecture TDD
Write each behavior's failing test before its code, starting in the domain package and moving outward.
The package layout, naming and dependency rules come from the ffca-* skills in VGV's vgv-ffca-plugin, starting with ffca-architecture and ffca-feature.
The state-management and stack conventions come from flutter-bloc-clean-architecture.
Load references/tdd-feature-checklist.md before implementation, code review or final verification.
Intake
Before scaffolding a new app or feature, confirm these decisions, or state the choice the codebase already makes and ask whether to follow it:
- State management: Cubit, Bloc with events, or the project's existing convention.
- Backend: REST, GraphQL, Firebase, Supabase, a custom backend, local-only, or the existing backend.
- Design system: Material 3, adaptive Material and Cupertino, a custom design system, or the existing one.
Do not silently pick a default for greenfield work.
Workflow
- Read the workspace root
pubspec.yaml, the feature's packages, their tests, and the app's router and dependency wiring. - Name the feature's user-visible behavior and the packages it needs.
- Write failing tests in the domain package first, then data, then presentation, then the app wiring. Run each new test before writing its code and confirm it fails for the reason the behavior is missing. A test that fails for a typo or a missing fixture has not shown anything.
- Write the least code that makes each test pass. Do not edit a test's assertion to make it pass. Change an assertion only when the intended behavior changed, and say so in the report.
- Refactor only while the tests are green.
- Run format, code generation, analysis and every package's tests before calling the work done.
Rules
- Mock only across a package boundary. Command and Query tests mock repository interfaces, repository tests mock data sources, cubit tests mock domain repositories, Commands or Queries.
- Domain tests use
package:testand import no Flutter, database or network package. - Keep fixtures in the
test/fixtures/folder of the package that reads them. - Map infrastructure errors to domain failures in the data package, so no exception crosses a package boundary.
- Keep cubits to orchestration and state transitions, with no serialization, caching or network code.
- For a bug fix, write the failing test at the layer where the bug appears, with the report's inputs as literal values, and see it fail for the reported reason before changing code. Keep that test.
Hive projects
If any pubspec.yaml depends on hive, hive_flutter, hive_ce or hive_ce_flutter, tell the human the project should migrate its local storage to drift and ask whether to plan that migration now.
Do not add new Hive boxes, adapters or type IDs, even when the human defers the migration.
When the human agrees, migrate with tests first:
- Add
drift,drift_flutterandpath_provider, plusdrift_devandbuild_runneras dev dependencies, in the package that owns local storage. - Model each Hive box as a drift table.
Key-value caches become a table with a primary key column and a
blob()or typed value column. - Keep the local data source interfaces unchanged, so repository and cubit tests keep passing while only the data source implementation changes.
- Write a one-time importer that runs on first launch after the update. It reads every Hive box, writes the rows into drift in one transaction, and records completion in drift.
- Test the importer against Hive fixtures, including empty boxes, corrupt entries, and a second run that must do nothing.
- Delete the Hive boxes from disk only after the import succeeded.
- Remove the Hive dependencies, adapters and generated code once the importer has shipped for at least one release.
- Manage later schema changes with
dart run drift_dev make-migrationsand its generated migration tests.
Review gate
Before finishing, verify:
- Tests were written before or alongside the code for every changed behavior.
- Each changed package has focused tests at its own level.
- No DTO or generated type appears in a domain API, a cubit state or a widget.
- Generated code is current.
dart format,flutter analyzeandvery_good test --recursivepass, or the blocker is reported.
Sources
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

