clean_arch
A command-line tool that scaffolds Flutter projects with either:
- Clean Architecture (layered
data/domain/presentationfeature modules), or - Normal Folder Architecture (modular feature folders with
model/services/provider/screens).
Run one command to initialize your project structure, then generate feature modules as your app grows.
Installation
dart pub global activate clean_arch
Adding to PATH
Make sure ~/.pub-cache/bin (or %APPDATA%\Pub\Cache\bin on Windows) is on your PATH.
macOS (zsh - default shell):
echo 'export PATH="$PATH":"$HOME/.pub-cache/bin"' >> ~/.zshrc
source ~/.zshrc
Linux (bash):
echo 'export PATH="$PATH":"$HOME/.pub-cache/bin"' >> ~/.bashrc
source ~/.bashrc
Windows (PowerShell):
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";$env:LOCALAPPDATA\Pub\Cache\bin", "User")
Usage
Initialise architecture
Run this once at the root of your Flutter project:
clean_arch init
The CLI now prompts you to choose:
- Clean Architecture
- Normal Folder Architecture
You can also skip the prompt:
clean_arch init clean
clean_arch init normal
clean_arch normal init
Default packages
init also runs flutter pub add to add these packages to your
pubspec.yaml. No versions are pinned, so pub picks the latest versions
compatible with your Flutter SDK:
flutter_bloc, flutter_svg, internet_connection_checker_plus, pinput,
url_launcher, shimmer, nepali_date_picker, share_plus, path_provider,
http_parser, image_picker, dio, file_picker, flutter_dotenv,
socket_io_client, connectivity_plus, flutter_secure_storage, get_it,
intl, equatable, latlong2, open_filex, shared_preferences,
in_app_update, cached_network_image
If adding them all at once fails, each package is retried on its own and any
that still fail are listed so you can add them manually. To scaffold without
adding packages, pass --no-deps:
clean_arch init clean --no-deps
clean_arch normal init --no-deps
The generated
app_update_service.dartimportsin_app_update. If you use--no-deps, runflutter pub add in_app_updateyourself or delete that file.
In-app updates
Both architectures generate lib/core/services/app_update_service.dart, which
uses Google Play's in-app updates API (via in_app_update) to prompt users
when a newer version is on the Play Store. It is already wired in:
- Clean Architecture:
MainAppcallsAppUpdateService.instance.checkForUpdate()after the first frame. - Normal Folder Architecture:
AppService.bootstrap()calls it.
By default the update downloads in the background (flexible update). For a
blocking full-screen update, call checkForUpdate(immediate: true). The check
only runs on Android builds installed from the Play Store and does nothing on
other platforms or in debug builds.
You can check the version or print help at any time:
clean_arch version
clean_arch help
Generated structure for Clean Architecture:
lib/
core/
app/ → main_app.dart
config/ → app_config.dart
constants/ → app_constants.dart
data/
datasources/
local/ → local_datasource.dart
remote/ → remote_datasource.dart
repositories/ → base_repository.dart
database/ → app_database.dart
date_picker/ → app_date_picker.dart
di/ → injection_container.dart
errors/ → failures.dart, exceptions.dart
locations/ → location_service.dart
models/ → base_model.dart
navigation/ → app_navigator.dart
network/
network_info.dart
interceptors/ → auth_interceptor.dart
platform/ → platform_info.dart
router/ → app_router.dart
security/ → security_service.dart
services/ → api_service.dart, app_update_service.dart
shared/
widgets/ → custom_button.dart
storage/ → local_storage.dart
sync/ → sync_manager.dart
theme/ → app_theme.dart
utils/ → extensions.dart
validation/ → form_validators.dart
features/
Generated structure for Normal Folder Architecture:
lib/
core/
widgets/
app_button.dart
utils/
app_utils.dart
controllers/
app_controller.dart
helper/
app_helper.dart
services/
app_service.dart
app_update_service.dart
theme/
app_theme.dart
route/
app_router.dart
storage/
app_storage.dart
features/
auth/
model/
auth_model.dart
services/
auth_service.dart
provider/
auth_provider.dart
screens/
auth_screen.dart
home/
model/
home_model.dart
services/
home_service.dart
provider/
home_provider.dart
screens/
home_screen.dart
Note: clean_arch init normal does not generate main.dart or app.dart
because Flutter already creates them when you create a new app.
Generate a feature module
clean_arch feature <name>
Explicit normal architecture feature command:
clean_arch normal feature <name>
Example (auto-detect mode):
clean_arch feature auth
clean_arch feature <name> now works for both architecture styles:
- In a Clean Architecture project, it creates
data/domain/presentationlayers. - In a Normal Folder project, it creates:
screens/<name>_screen.dartservices/<name>_service.dartprovider/<name>_provider.dartmodel/<name>_model.dart
Use clean_arch normal feature <name> when you want to force normal feature
generation even if clean architecture files exist in the project.
Feature names are automatically normalized to snake_case, so
clean_arch feature "User Profile" and clean_arch feature userProfile both
generate a user_profile module. Names that can't form a valid Dart identifier
(e.g. starting with a digit) are rejected with a clear error.
Generated structure for auth:
(Clean Architecture mode)
lib/features/auth/
data/
datasources/ → auth_remote_datasource.dart, auth_local_datasource.dart
models/ → auth_model.dart
repositories/ → auth_repository_impl.dart
domain/
entities/ → auth_entity.dart
repositories/ → auth_repository.dart
usecases/ → get_auth_usecase.dart
presentation/
bloc/ → auth_bloc.dart, auth_event.dart, auth_state.dart
screens/ → auth_screen.dart
widgets/ → auth_card.dart
(Normal Folder mode)
lib/features/auth/
model/
auth_model.dart
services/
auth_service.dart
provider/
auth_provider.dart
screens/
auth_screen.dart
Programmatic API
You can also call the generators directly from Dart code:
import 'package:clean_arch/generators/architecture_generator.dart';
import 'package:clean_arch/generators/feature_generator.dart';
void main(List<String> args) {
final useNormalArchitecture = args.contains('--normal');
if (useNormalArchitecture) {
generateStandardArchitecture();
generateFeature('profile', architectureType: 'normal');
} else {
generateArchitecture();
generateFeature('auth', architectureType: 'clean');
}
}
See the example/ directory for a runnable sample.
Requirements
- Dart SDK
>=3.8.1 - Run from the root of your Flutter project so files are created at the
correct
lib/path. - The Flutter SDK on your
PATH(used byinitto runflutter pub add).
Author
Developed by Abhishek Sharma
- Portfolio: abhishek-sharma.com.np
- GitHub: @4bhisheksharma
Contributing
Pull requests are welcome! See CONTRIBUTING or open an issue at the issue tracker.
License
Libraries
- clean_arch
- Clean Architecture scaffold generator for Flutter projects.
- commands/feature_command
- commands/init_command
- generators/architecture_generator
- generators/dependency_installer
- generators/feature_generator
- templates/templates
- utils/file_helper
- utils/logger
- utils/naming