Twafok CLI
A command-line tool that scaffolds Clean Architecture features for Flutter projects — generate complete features, add use cases, and wire up dependency injection and barrel files automatically.
Overview
Building features with Clean Architecture means creating a lot of boilerplate: entities, models, repositories, data sources, use cases, cubits, states, and screens — each in its own layer, each importing the others. Twafok CLI does all of that for you with a single command.
It generates a consistent folder structure across the domain, data, and presentation layers, follows the BLoC/Cubit pattern, and keeps your dependency injection and barrel (export) files in sync as your feature grows.
Features
- Full feature scaffolding — one command creates the entire layered structure for a new feature.
- Incremental use cases — add new use cases to an existing feature without touching the boilerplate by hand; the tool updates the repository, data source, and cubit for you.
- Automatic dependency injection — generates a
*_di.dartfile that registers data sources, repositories, use cases, and cubits withget_it. - Barrel file generation — produces a single export file per feature so the rest of your app imports one path instead of many.
- Auto-formatting — runs
dart formatanddart fix --applyafter generation so the output is clean and lint-friendly. - Smart path detection — most commands can auto-detect the current feature when run from inside its folder.
Generated Structure
Running a feature creation command produces the following layout under lib/features/<feature_name>/:
lib/features/<feature_name>/
├── data/
│ ├── data_sources/ # Remote data source (Dio-based)
│ ├── models/ # Model extending the domain entity
│ └── repositories/ # Repository implementation
├── domain/
│ ├── entities/ # Equatable entity
│ ├── repositories/ # Abstract base repository
│ └── use_cases/ # Use case + Request/Response classes
├── presentation/
│ ├── controllers/ # Cubit + State
│ ├── screens/ # Screen widget
│ └── widgets/ # Feature-specific widgets
├── <feature_name>.dart # Barrel file (auto-generated exports)
└── <feature_name>_di.dart # Dependency injection (auto-generated)
Installation
Twafok CLI is a Dart command-line application. You need the Dart SDK (version 3.0 or newer) installed.
1. Clone the repository
git clone https://github.com/muhamaadessam/twafok_cli.git
cd twafok_cli
2. Install dependencies
dart pub get
3. Activate the tool globally
dart pub global activate --source path .
This registers the twafok executable so you can run it from any Flutter project directory.
Note: Make sure Dart's
pubglobal bin directory is on yourPATH. On Windows it is typically%LOCALAPPDATA%\Pub\Cache\bin; on macOS/Linux it is$HOME/.pub-cache/bin.
Alternatively, you can run the tool directly without activating it:
dart run bin/twafok_cli.dart <command> [arguments]
Usage
Run all commands from the root of your Flutter project.
twafok_cli <command> [arguments] [options]
Commands
| Command | Aliases | Description |
|---|---|---|
create_feature |
create, cr |
Create a complete feature with all layers |
add_usecase |
add, add-use-case |
Add a new use case to an existing feature |
generate_di |
gen-di |
(Re)generate the dependency injection file |
generate_paths |
gen-paths, gen-barrel |
(Re)generate the barrel/export file |
help |
--help, -h |
Show usage information |
Options
| Option | Abbreviation | Description | Default |
|---|---|---|---|
--package |
-p |
Package name used in generated imports | twafok |
--help |
-h |
Show help for the command | — |
The
generate_pathscommand reads the package name directly from your project'spubspec.yaml, so you usually don't need to pass--packageto it.
Examples
Create a new feature
twafok_cli create_feature Profile
twafok_cli create Authentication # using the shortcut alias
This creates the full lib/features/Profile/ structure, generates the DI and barrel files, then formats the project.
Add a use case to an existing feature
Provide the feature path and the action name:
twafok_cli add_usecase lib/features/Profile update_profile
Or run it from inside the feature folder and let the tool detect the path:
cd lib/features/Profile
twafok_cli add update_profile
The tool generates the new use case file (with Request and Response classes) and updates the base repository, repository implementation, remote data source, and cubit accordingly.
Regenerate dependency injection
twafok_cli generate_di lib/features/Profile
twafok_cli gen-di # auto-detects the feature when run inside its folder
Regenerate the barrel file
twafok_cli generate_paths lib/features/Profile
twafok_cli gen-paths # auto-detects the feature when run inside its folder
How It Works
Twafok CLI is organized into a few clear layers:
bin/twafok_cli.dart— the entry point. It parses the top-level command and delegates to the matching command handler.lib/commands/— one class per command (CreateFeatureCommand,AddUsecaseCommand,GenerateDiCommand,GeneratePathsCommand). Each parses its own arguments and orchestrates the work.lib/generators/— focused generators that create or update individual artifacts (use case, cubit, data source, repository).lib/services/— shared helpers:NamingUtilshandles all the naming conventions (snake_case, PascalCase, class names), andFileUtilshandles file lookup and code injection.lib/templates/— code templates used during generation.
When you add a use case, the generators don't rewrite existing files from scratch — they insert the new method signatures and fields before the closing brace of the relevant class, so your existing code is preserved.
Generated Code Conventions
The generated code assumes your project provides a small set of shared base classes (commonly placed in a core library), including:
BaseUseCase<Response, Request>— base class for use casesBaseCubit<State>andBaseState— base classes for state managementBaseView<Cubit, State>— base widget for screensFailure/ServerFailure— error types used withEitherfromdartzDioHelper— a wrapper arounddiofor network calls
Generated files are marked with a // GENERATED FILE - DO NOT EDIT header. Files that you are expected to customize (such as Request field definitions and API endpoints) are flagged in the command's "Next steps" output.
Dependencies
| Package | Purpose |
|---|---|
args |
Parses command-line arguments and options |
path |
Cross-platform file path manipulation |
io |
I/O utilities for command-line apps |
Roadmap
Some areas are still in progress or planned (a few modules in the codebase are currently commented out):
- Configurable templates so teams can adapt the generated code to their own base classes.
- A
--dry-runflag to preview generated files before writing them. - Unit tests covering the generators and naming utilities.
Contributions and ideas are welcome.
Contributing
- Fork the repository.
- Create a feature branch:
git checkout -b feature/my-improvement. - Make your changes and run
dart format .anddart analyze. - Commit and push, then open a Pull Request.
Please open an issue first for larger changes so we can discuss the approach.
License
This project is licensed under the MIT License.
Author
Mohamed Essam — @muhamaadessam
Libraries
- commands/add_usecase_command
- commands/create_feature_command
- commands/generate_di_command
- commands/generate_paths_command
- generators/base_repository_generator
- generators/cubit_generator
- generators/datasource_generator
- generators/repository_generator
- generators/usecase_generator
- services/file_service
- services/injection_service
- services/naming_service
- templates/usecase_template