clean_architect 0.1.6 copy "clean_architect: ^0.1.6" to clipboard
clean_architect: ^0.1.6 copied to clipboard

A configurable CLI generator for clean architecture Flutter and Dart feature modules.

clean_architect #

A configurable Dart CLI generator for Clean Architecture Flutter/Dart projects.

clean_architect generates boring, predictable architecture files that you can edit immediately. The generator does not try to hide your app behind runtime abstractions. The flexibility lives in clean_architect.yaml: paths, layer layout, state management, network client, local storage, model style, and dependency injection style.

Install #

dart pub global activate clean_architect

After global activation you can run the executable from any folder:

clean_architect init
clean_architect create architecture
clean_architect create auth
clean_architect create feature orders

Empty Folder Usage #

Use the global executable when generating into an empty folder:

mkdir my_app
cd my_app
clean_architect create architecture

Do not use dart run clean_architect ... in an empty folder. dart run needs a local pubspec.yaml before the CLI can start. Use dart run clean_architect ... only when developing this package from its own checkout or from another Dart project that already has a pubspec.yaml.

Commands #

clean_architect init
clean_architect doctor
clean_architect create architecture
clean_architect create base
clean_architect create auth
clean_architect create feature <name>
clean_architect create usecase <name> --feature <feature>
clean_architect create repository <feature>

Examples:

clean_architect init
clean_architect create architecture
clean_architect create feature orders
clean_architect create auth
clean_architect create usecase login --feature auth
clean_architect create repository auth
clean_architect doctor

Useful flags:

clean_architect init --dry-run
clean_architect init --force

clean_architect create architecture --dry-run
clean_architect create auth --dry-run
clean_architect create auth --overwrite
clean_architect create auth --force
clean_architect create feature profile --skip-presentation

clean_architect create auth --state getx
clean_architect create auth --state none
clean_architect create auth --network dio
clean_architect create auth --network abstract
clean_architect create auth --storage secure_storage
clean_architect create auth --storage abstract
clean_architect create auth --di injectable
clean_architect create auth --dependency-injection manual

--overwrite and --force are required before existing generated files are replaced.

Configuration File #

Run:

clean_architect init

This creates clean_architect.yaml:

clean_architect:
  structure: layered_packages # layered_packages or feature_first
  state_management: getx # getx or none
  network: dio # dio or abstract
  local_storage: secure_storage # secure_storage or abstract
  dependency_injection: manual # manual or injectable
  use_asset_generator: true
  models:
    use_freezed: true
    use_json_serializable: true
  paths:
    domain: domain/lib
    data: data/lib/features
    presentation: presentation/lib
    di: di/lib

Configuration Reference #

Key Values Default What it controls
structure layered_packages, feature_first layered_packages How feature paths are resolved from the configured layer paths.
state_management getx, none getx Presentation controller/page style.
network dio, abstract dio Remote data source style and generated data dependencies.
local_storage secure_storage, abstract secure_storage Local auth credential storage style.
dependency_injection manual, injectable manual Manual DI builder files or injectable/get_it setup files and annotations.
use_asset_generator true, false true Whether presentation gets asset_generator_kit.yaml and the asset generator dependency.
models.use_freezed true, false true Whether entities/DTOs use Freezed.
models.use_json_serializable true, false true Whether DTOs include JSON serialization parts/factories.
paths.domain path domain/lib Domain layer feature root.
paths.data path data/lib/features Data layer feature root.
paths.presentation path presentation/lib Presentation layer root.
paths.di path di/lib Dependency injection layer root.

The config parser also recognizes local_storage: shared_preferences, but the current templates only generate concrete storage code for secure_storage; use abstract when you want to wire your own storage implementation.

CLI overrides are intentionally small and only affect the current command. They do not rewrite clean_architect.yaml.

Generated Project Shape #

The default architecture is a multi-package Flutter/Dart workspace shape:

my_app/
  domain/
    pubspec.yaml
    lib/
      features/
        base_feature/
          entities/
          repositories/
          usecases/

  data/
    pubspec.yaml
    lib/
      features/
        base_feature/
          remote/
            models/
          local/
            models/
          repositories/

  di/
    pubspec.yaml
    lib/

  presentation/
    pubspec.yaml
    analysis_options.yaml
    asset_generator_kit.yaml
    assets/
      images/
      icons/
    lib/
      main.dart
      widgets/
      pages/
      utils/
      controllers/
      constants/

Every layer gets its own pubspec.yaml:

  • domain is a pure Dart package for entities, repository contracts, and use cases.
  • data is a Dart/Flutter package for DTOs, API services, local sources, mappers, and repository implementations.
  • di is a Dart package that connects domain and data dependencies.
  • presentation is a runnable Flutter package with main.dart, Flutter dependencies, and UI folders.

After generation, run Flutter setup inside presentation when you want a complete Flutter platform project:

cd presentation
flutter create .
flutter pub get

Run dart pub get in the other layer packages as needed.

Structure Modes #

Default Layered Packages #

clean_architect:
  structure: layered_packages
  paths:
    domain: domain/lib
    data: data/lib/features
    presentation: presentation/lib
    di: di/lib

clean_architect create auth creates:

domain/lib/features/auth/...
data/lib/features/auth/...
di/lib/auth_di.dart
presentation/lib/controllers/auth_controller.dart
presentation/lib/pages/login_page.dart
presentation/lib/widgets/login_view_item.dart

Custom Layer Paths #

You can point the layers to existing packages or app folders:

clean_architect:
  structure: layered_packages
  paths:
    domain: packages/domain/lib/modules
    data: packages/data/lib/modules
    presentation: apps/customer_app/lib
    di: packages/di/lib

Then clean_architect create feature profile creates feature files under those configured roots.

Feature First #

feature_first is available for projects that still want feature-based grouping while keeping the same layer packages:

clean_architect:
  structure: feature_first
  paths:
    domain: domain/lib
    data: data/lib/features
    presentation: presentation/lib
    di: di/lib

Current path resolution places domain files under domain/lib/features/<feature> and data files under data/lib/features/<feature>. Presentation files stay in shared presentation folders: pages, controllers, and widgets.

create architecture #

clean_architect create architecture

Generates the layer packages and default folders only. It does not generate auth code.

Default placeholder feature name:

domain/lib/features/base_feature
data/lib/features/base_feature

Use this when you want the clean architecture project skeleton first, then add features later.

create feature <name> #

clean_architect create feature orders

Generates a generic feature module.

Domain:

domain/lib/features/orders/entities/orders_entity.dart
domain/lib/features/orders/repositories/orders_repository.dart
domain/lib/features/orders/usecases/get_orders_list_use_case.dart

Data:

data/lib/features/orders/remote/models/orders_dto.dart
data/lib/features/orders/remote/orders_api_service.dart
data/lib/features/orders/local/models/.gitkeep
data/lib/features/orders/local/orders_local_data_source.dart
data/lib/features/orders/mappers/orders_mapper.dart
data/lib/features/orders/repositories/orders_repository_impl.dart

Presentation, unless --skip-presentation is used:

presentation/lib/controllers/orders_controller.dart
presentation/lib/pages/orders_page.dart
presentation/lib/widgets/orders_view_item.dart

The generic feature is intentionally minimal: entity, DTO, mapper, repository contract, repository implementation, list use case, local source, Retrofit API service, controller, page, and view item.

create auth #

clean_architect create auth

Generates a concrete auth starter feature.

Domain:

domain/lib/features/auth/entities/auth_token_entity.dart
domain/lib/features/auth/entities/auth_credentials_entity.dart
domain/lib/features/auth/repositories/auth_repository.dart
domain/lib/features/auth/usecases/login_use_case.dart
domain/lib/features/auth/usecases/logout_use_case.dart
domain/lib/features/auth/usecases/save_auth_credentials_use_case.dart
domain/lib/features/auth/usecases/get_auth_credentials_use_case.dart
domain/lib/features/auth/usecases/clear_auth_credentials_use_case.dart

Data:

data/lib/features/auth/remote/models/auth_token_dto.dart
data/lib/features/auth/remote/models/login_request_dto.dart
data/lib/features/auth/remote/auth_api_service.dart
data/lib/features/auth/local/models/.gitkeep
data/lib/features/auth/local/auth_local_data_source.dart
data/lib/features/auth/mappers/auth_token_mapper.dart
data/lib/features/auth/repositories/auth_repository_impl.dart

Presentation, unless --skip-presentation is used:

presentation/lib/controllers/auth_controller.dart
presentation/lib/pages/login_page.dart
presentation/lib/widgets/login_view_item.dart

The generated remote API service uses Dio + Retrofit style:

@lazySingleton
@RestApi(baseUrl: '')
abstract class AuthApiService {
  @factoryMethod
  factory AuthApiService(@Named("auth_dio") Dio dio) = _AuthApiService;

  @POST('/authorization/token/')
  Future<AuthTokenDto> login(@Body() Map<String, dynamic> body);
}

The generated auth controller uses GetIt.instance.get<LoginUseCase>(), and the GetX page registers the controller in initState with Get.put(AuthController()).

Dependency Injection Modes #

Manual #

dependency_injection: manual

Manual mode generates simple DI builder files, for example:

di/lib/auth_di.dart
di/lib/orders_di.dart

Use this when you want explicit constructors and simple dependency wiring you can edit by hand.

Injectable #

dependency_injection: injectable

Injectable mode adds injectable/get_it dependencies and generates injector entry files:

domain/lib/injector.dart
data/lib/injector.dart
di/lib/di.dart

Generated classes receive injectable annotations where supported. After generation, run build runner in the generated packages that contain injectable/freezed/json_serializable code.

Model Modes #

Freezed + JSON Serializable #

models:
  use_freezed: true
  use_json_serializable: true

Entities and DTOs use Freezed. DTOs also include JSON serialization parts when JSON serialization is enabled.

Typical follow-up command in generated packages:

dart run build_runner build --delete-conflicting-outputs

Plain Dart Fallback #

models:
  use_freezed: false
  use_json_serializable: false

Entities and DTOs are generated as simple Dart classes.

State Management #

GetX #

state_management: getx

Presentation controllers extend GetxController, pages use Get.put(...), Get.find(...), and reactive values where needed.

None #

state_management: none

Presentation files are generated without GetX page wiring. This is useful when you want to connect Bloc, Riverpod, Provider, or another state system manually.

Network #

Dio #

network: dio

Generated remote services use Dio + Retrofit imports and annotations. The data package receives the relevant dependencies.

Abstract #

network: abstract

Use this when you want the generated repositories and source boundaries but plan to implement networking yourself.

Local Storage #

Secure Storage #

local_storage: secure_storage

Auth local source uses flutter_secure_storage for credential persistence.

Abstract #

local_storage: abstract

Auth local source contains TODO methods so you can wire Hive, shared preferences, a database, encrypted storage, or another persistence mechanism yourself.

Presentation Package #

The generated presentation package includes:

presentation/lib/main.dart
presentation/lib/widgets/
presentation/lib/pages/
presentation/lib/utils/
presentation/lib/controllers/
presentation/lib/constants/
presentation/assets/images/
presentation/assets/icons/

When use_asset_generator: true, it also includes:

presentation/asset_generator_kit.yaml

and adds assetgeneratorkit to presentation/pubspec.yaml.

Safety #

By default, existing files are not overwritten.

Preview generated files:

clean_architect create auth --dry-run

Overwrite intentionally:

clean_architect create auth --overwrite

or:

clean_architect create auth --force

Doctor #

clean_architect doctor

doctor loads clean_architect.yaml, checks whether configured paths exist, and prints dependency reminders for selected options such as Dio, GetX, and secure storage.

Publishing / Development Notes #

When working on this package locally:

dart format lib test bin
dart analyze
dart test
dart pub publish --dry-run

Run dart pub publish --dry-run before publishing to verify pub.dev metadata and package contents.

0
likes
0
points
1.06k
downloads

Publisher

verified publisherpinz.dev

Weekly Downloads

A configurable CLI generator for clean architecture Flutter and Dart feature modules.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

args, collection, mason_logger, meta, path, yaml

More

Packages that depend on clean_architect