flutter-project-init
Creates a new Flutter project with Clean Architecture, domain pattern boilerplate, and production-ready setup
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Creates a new Flutter project with Clean Architecture, domain pattern boilerplate, and production-ready setup
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
You MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation using Clean Architecture principles.
Use when you have a written implementation plan to execute with review checkpoints
Use when facing 2+ independent Flutter tasks that can be worked on without shared state or sequential dependencies
Use when you have a design or requirements for a multi-step Flutter feature, before touching code
Use when executing Flutter implementation plans with independent tasks in the current session
Use when writing tests for Flutter code - follows priority-based testing (Repository → State → Widget) after implementation
| name | flutter-project-init |
| description | Creates a new Flutter project with Clean Architecture, domain pattern boilerplate, and production-ready setup |
Use when: "new project", "create project", "start project", "init flutter"
Step 1: Project Info → name, org, description
Step 2: Domain Pattern → Simple/Stateful/Categorized/Tracked/Relational/Custom
Step 3: Tech Stack → State Management, Features
Step 4: Generate & Verify → create, build, analyze
Ask user for:
| Field | Example | Required |
|---|---|---|
| Project name | my_app (snake_case) | Yes |
| Organization | com.example | Yes |
| Description | "Task management app" | Yes |
| Entity name | Task, Note, Expense | Yes |
Ask user to choose:
| Pattern | Examples | Generated Structure |
|---|---|---|
| Simple | Note, Memo, Bookmark | Single-entity CRUD |
| Stateful | Todo, Task, Order | Includes a status field (done/in-progress, etc.) |
| Categorized | Expense, Product, Recipe | Includes a category relationship |
| Tracked | Habit, Workout, Study | Time/date-based tracking |
| Relational | Blog (User-Post-Comment) | Multi-entity relationships |
| Custom | - | User-defined fields |
// Entity
@freezed
sealed class Note with _$Note {
const factory Note({
required String id,
required String title,
required String content,
required DateTime createdAt,
DateTime? updatedAt,
}) = _Note;
}
// Entity with status
@freezed
sealed class Task with _$Task {
const factory Task({
required String id,
required String title,
required String description,
@Default(TaskStatus.pending) TaskStatus status,
required DateTime createdAt,
DateTime? completedAt,
}) = _Task;
}
enum TaskStatus { pending, inProgress, completed, cancelled }
// Entity with category relation
@freezed
sealed class Expense with _$Expense {
const factory Expense({
required String id,
required String title,
required double amount,
required String categoryId,
required DateTime date,
String? note,
}) = _Expense;
}
@freezed
sealed class Category with _$Category {
const factory Category({
required String id,
required String name,
required String icon,
required String color,
}) = _Category;
}
// Entity with time tracking
@freezed
sealed class Habit with _$Habit {
const factory Habit({
required String id,
required String name,
required String description,
required HabitFrequency frequency,
required List<DateTime> completedDates,
required int currentStreak,
required int bestStreak,
required DateTime createdAt,
}) = _Habit;
}
enum HabitFrequency { daily, weekly, monthly }
// Multiple related entities
@freezed
sealed class User with _$User {
const factory User({
required String id,
required String name,
required String email,
required DateTime createdAt,
}) = _User;
}
@freezed
sealed class Post with _$Post {
const factory Post({
required String id,
required String authorId,
required String title,
required String content,
required DateTime createdAt,
@Default(0) int likeCount,
}) = _Post;
}
@freezed
sealed class Comment with _$Comment {
const factory Comment({
required String id,
required String postId,
required String authorId,
required String content,
required DateTime createdAt,
}) = _Comment;
}
| Option | Description |
|---|---|
| Riverpod (Recommended) | Modern, compile-safe, testable |
| BLoC | Event-driven, enterprise-grade |
| Preset | Includes |
|---|---|
| Minimal | Core only (Freezed, Drift, DI) |
| Essential | + GoRouter, Dio, Error handling |
| Full | + Auth, Localization, Responsive |
Prerequisite: a recent stable Flutter SDK (Dart >= 3.9). On older SDKs pub
silently resolves a broken -dev prerelease of freezed that generates nothing.
Check flutter --version and run flutter upgrade first if outdated.
Install EVERYTHING your preset needs in ONE flutter pub add command — a
single resolver pass. Sequential installs wedge the solver: each pass pins
the newest carets, and the codegen cluster (freezed / drift_dev /
injectable_generator / riverpod_generator) rides different analyzer majors,
so a later group can become unsolvable against what an earlier group locked.
One pass lets pub pick a mutually compatible all-stable set.
# Full preset + Riverpod (remove what your preset doesn't need — but never
# split runtime and dev: codegen packages into separate commands).
# path_provider/path are required by app_database.dart.
# fpdart = Either for error handling (dartz is unmaintained).
flutter pub add freezed_annotation drift path_provider path get_it injectable flutter_riverpod riverpod_annotation go_router dio fpdart easy_localization responsive_framework dev:freezed dev:build_runner dev:injectable_generator dev:drift_dev dev:riverpod_generator
# Using BLoC instead of Riverpod: drop flutter_riverpod, riverpod_annotation
# and dev:riverpod_generator from the command above and run:
flutter pub add flutter_bloc
# Optional (Full preset):
flutter pub add firebase_auth
After installing, check pubspec.yaml for -dev/-beta prereleases. One may
appear while the ecosystem migrates across analyzer majors; that alone is not
fatal, but it makes Step 4.6 (flutter analyze after codegen) mandatory
evidence — if generation silently produced nothing, analyze fails there.
flutter create --org <org> --project-name <name> <name>
cd <name>
lib/
├── core/
│ ├── constants/
│ │ └── app_constants.dart
│ ├── database/
│ │ └── app_database.dart
│ ├── di/
│ │ └── injection.dart
│ ├── errors/
│ │ ├── exceptions.dart
│ │ └── failures.dart
│ ├── router/
│ │ └── app_router.dart
│ ├── theme/
│ │ ├── app_colors.dart
│ │ └── app_theme.dart
│ └── utils/
│ └── extensions.dart
├── features/
│ └── <entity>/
│ ├── domain/
│ │ ├── entities/
│ │ │ └── <entity>.dart
│ │ ├── repositories/
│ │ │ └── <entity>_repository.dart
│ │ └── usecases/
│ │ ├── create_<entity>.dart
│ │ ├── delete_<entity>.dart
│ │ ├── get_<entity>s.dart
│ │ └── update_<entity>.dart
│ ├── data/
│ │ ├── datasources/
│ │ │ └── <entity>_local_datasource.dart
│ │ ├── models/
│ │ │ └── <entity>_model.dart
│ │ └── repositories/
│ │ └── <entity>_repository_impl.dart
│ └── presentation/
│ ├── bloc/ # or providers/
│ │ ├── <entity>_bloc.dart
│ │ ├── <entity>_event.dart
│ │ └── <entity>_state.dart
│ ├── pages/
│ │ ├── <entity>_list_page.dart
│ │ └── <entity>_detail_page.dart
│ └── widgets/
│ └── <entity>_card.dart
├── shared/
│ └── widgets/
│ └── loading_widget.dart
└── main.dart
import 'package:freezed_annotation/freezed_annotation.dart';
part 'failures.freezed.dart';
@freezed
sealed class Failure with _$Failure {
const factory Failure.server({required String message, int? code}) = ServerFailure;
const factory Failure.cache({required String message}) = CacheFailure;
const factory Failure.network({@Default('No internet connection') String message}) = NetworkFailure;
const factory Failure.validation({required String message}) = ValidationFailure;
}
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
part 'app_database.g.dart';
// Tables will be added per domain pattern
@DriftDatabase(tables: [])
class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection());
@override
int get schemaVersion => 1;
}
LazyDatabase _openConnection() {
return LazyDatabase(() async {
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(p.join(dbFolder.path, 'app.db'));
return NativeDatabase.createInBackground(file);
});
}
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'injection.config.dart';
final getIt = GetIt.instance;
@InjectableInit(preferRelativeImports: true)
Future<void> configureDependencies() async => getIt.init();
Based on selected preset, add all required dependencies.
flutter pub get
dart run build_runner build --delete-conflicting-outputs
flutter analyze
Must pass with 0 errors. Info/warning level issues are acceptable.
If errors exist:
dart run build_runner buildflutter analyzegit init
git add .
git commit -m "Initial commit: <project_name> with Clean Architecture
- Domain pattern: <selected_pattern>
- State management: <Riverpod/BLoC>
- Features: <selected_preset>
🤖 Generated with flutter-craft"
flutter pub get successfuldart run build_runner build successfulflutter analyze returns 0 errorsAfter completion, inform:
✅ Project '<name>' created successfully!
📁 Structure: Clean Architecture
📦 Pattern: <selected_pattern>
🔄 State: <Riverpod/BLoC>
✨ Features: <preset>
Next steps:
1. cd <name>
2. flutter run
3. Use /brainstorm to plan your first feature
For detailed code templates per pattern, see:
references/simple-pattern.mdreferences/stateful-pattern.mdreferences/categorized-pattern.mdreferences/tracked-pattern.mdreferences/relational-pattern.mdNote: The Custom pattern has no dedicated template because you design the user-defined fields yourself.