πŸš€ SM CLI β€” Flutter Clean Architecture Generator

A powerful CLI tool to generate production-ready Flutter projects with clean architecture, multiple state management options, and feature-based structure.


πŸ“¦ Installation

dart pub global activate sm_cli

Make sure Dart is in your PATH:

export PATH="$PATH":"$HOME/.pub-cache/bin"

✨ Features

  • ⚑ Flutter project initializer with clean architecture
  • 🧩 Feature-based folder structure (Data, Domain, Presentation)
  • πŸ”„ Multiple state management β€” Riverpod, Bloc, GetX, Provider
  • 🌐 API layer generator (Dio, interceptors, response wrapper)
  • πŸ›£οΈ GoRouter integration with auto route generation
  • 🎨 Theme setup (light + dark)
  • πŸ’Ύ Project config auto-saved (no need to specify state management every time)

πŸš€ Quick Start

# 1. Install
dart pub global activate sm_cli

# 2. Create project
sm init my_app

# 3. Generate feature
sm make feature my_app auth

# 4. Generate API layer
sm make api my_app

# 5. List features
sm list my_app

# 6. Run
cd my_app && flutter run

πŸ“‹ Commands

sm init <project_name>

sm init my_app
sm init my_app --riverpod
sm init my_app --bloc
sm init my_app --getx
sm init my_app --provider

sm make feature <project_name> <feature_name>

sm make feature my_app auth
sm make feature my_app home
sm make feature my_app profile

sm make api <project_name>

sm make api my_app

sm list <project_name>

sm list my_app

Prompts:

  • Select State Management (Riverpod / Bloc / GetX / Provider)
  • Enable GoRouter? (y/n)
  • Enable Theme? (y/n)

Or use flags to skip prompts:

sm init my_app --riverpod
sm init my_app --bloc
sm init my_app --getx
sm init my_app --provider

sm make feature <project_name> <feature_name>

Generates a complete feature with clean architecture structure.

sm make feature my_app auth
sm make feature my_app home
sm make feature my_app profile

State management is auto-detected from project config β€” no need to specify every time.


sm make api <project_name>

Generates a complete API layer using Dio.

sm make api my_app

πŸ“ Generated Structure

Project Structure

my_app/
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ constants/
β”‚   β”‚   β”œβ”€β”€ network/
β”‚   β”‚   β”‚   β”œβ”€β”€ dio_client.dart
β”‚   β”‚   β”‚   β”œβ”€β”€ api_endpoints.dart
β”‚   β”‚   β”‚   β”œβ”€β”€ response_wrapper.dart
β”‚   β”‚   β”‚   β”œβ”€β”€ network_exceptions.dart
β”‚   β”‚   β”‚   └── interceptors/
β”‚   β”‚   β”‚       └── logging_interceptor.dart
β”‚   β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”‚   β”œβ”€β”€ app_router.dart
β”‚   β”‚   β”‚   └── app_routes.dart
β”‚   β”‚   β”œβ”€β”€ theme/
β”‚   β”‚   β”‚   └── app_theme.dart
β”‚   β”‚   └── utils/
β”‚   β”œβ”€β”€ features/
β”‚   β”‚   └── auth/
β”‚   └── shared/
β”œβ”€β”€ .sm_cli_config
└── pubspec.yaml

Feature Structure β€” Riverpod / Provider

auth/
β”œβ”€β”€ data/
β”‚   β”œβ”€β”€ datasource/
β”‚   β”‚   └── auth_remote_datasource.dart
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   └── auth_model.dart
β”‚   └── repository/
β”‚       β”œβ”€β”€ auth_repository.dart
β”‚       └── auth_repository_impl.dart
β”œβ”€β”€ domain/
β”‚   β”œβ”€β”€ entities/
β”‚   β”‚   └── auth_entity.dart
β”‚   β”œβ”€β”€ repository/
β”‚   β”‚   └── auth_repository.dart
β”‚   └── usecases/
β”‚       └── auth_usecase.dart
└── presentation/
    β”œβ”€β”€ screens/
    β”‚   └── auth_screen.dart
    β”œβ”€β”€ providers/
    β”‚   └── auth_provider.dart
    └── widgets/

Feature Structure β€” Bloc

auth/
└── presentation/
    β”œβ”€β”€ screens/
    β”‚   └── auth_screen.dart
    β”œβ”€β”€ bloc/
    β”‚   β”œβ”€β”€ auth_bloc.dart
    β”‚   β”œβ”€β”€ auth_event.dart
    β”‚   └── auth_state.dart
    └── widgets/

Feature Structure β€” GetX

auth/
└── presentation/
    β”œβ”€β”€ screens/
    β”‚   └── auth_screen.dart
    β”œβ”€β”€ views/
    β”‚   └── auth_view.dart
    β”œβ”€β”€ controllers/
    β”‚   └── auth_controller.dart
    β”œβ”€β”€ bindings/
    β”‚   └── auth_binding.dart
    └── widgets/

πŸ”„ State Management

Feature Riverpod Bloc GetX Provider
State file _provider.dart _bloc.dart _controller.dart _provider.dart
Folder providers/ bloc/ controllers/ providers/
Extra β€” _event, _state _binding, _view β€”
Package flutter_riverpod flutter_bloc get provider

🌐 API Layer

Generated by sm make api:

// dio_client.dart β€” singleton Dio instance
final client = DioClient().dio;

// api_endpoints.dart β€” all your endpoints
class ApiEndpoints {
  static const baseUrl = "https://api.example.com";
  static const login = "/login";
}


πŸ›£οΈ Routing

Routes are auto-generated and updated when you run sm make feature:

// app_routes.dart β€” auto updated

class AppRoutes {
  static const home = '/';
  static const auth = '/auth'; // auto added by sm make feature
}

// app_router.dart β€” auto updated
final appRouter = GoRouter(
  routes: [
    GoRoute(
      path: AppRoutes.auth, // auto added by sm make feature
      builder: (context, state) => const AuthScreen(),
    ),
  ],
);

---

## 🎨 Theme

Light and dark theme pre-configured with Material 3:

```dart
MaterialApp.router(
  theme: AppTheme.lightTheme,
  darkTheme: AppTheme.darkTheme,
  routerConfig: appRouter,
);

πŸ“‹ All Flags

sm init <name>              # Interactive setup
sm init <name> --riverpod   # Skip prompt, use Riverpod
sm init <name> --bloc       # Skip prompt, use Bloc
sm init <name> --getx       # Skip prompt, use GetX
sm init <name> --provider   # Skip prompt, use Provider
sm --help                   # Show help
sm --version                # Show version

πŸ†š Why SM CLI?

SM CLI mason very_good_cli
Clean Architecture βœ… ❌ βœ…
Multiple state mgmt βœ… ❌ ❌ (Bloc only)
Auto route update βœ… ❌ ❌
API layer generator βœ… ❌ ❌
Project config βœ… ❌ ❌
Interactive CLI βœ… βœ… βœ…

πŸ› Issues & Feedback

Found a bug or have a suggestion? πŸ‘‰ Open an issue


πŸ“„ License

MIT License β€” see LICENSE