feature_gen_cli 1.4.1 copy "feature_gen_cli: ^1.4.1" to clipboard
feature_gen_cli: ^1.4.1 copied to clipboard

A command-line tool for generating feature modules.

Feature Gen #

pub package license pub points

Feature Gen is a Dart CLI that scaffolds clean-architecture feature modules for Flutter projects from a JSON schema.

Quick Start #

Requirements: Dart SDK >=3.10.4, a Flutter project with a valid pubspec.yaml, and dart on your PATH. Run the CLI from the Flutter project root so pubspec.yaml resolution works.

# 1. Install
dart pub global activate feature_gen_cli

# 2. Run
feature_gen_cli <feature_name> <schema.json>
# Example: feature_gen_cli user example/user_schema.json

# Overwrite existing generated files (optional)
feature_gen_cli <feature_name> <schema.json> --overwrite

Feature names should be lowercase snake_case (the generated folder is lib/features/<feature_name>/).

CLI Options #

feature_gen_cli <feature_name> <schema.json> -o   # overwrite existing generated files
feature_gen_cli --version                          # print package version
feature_gen_cli --help                             # show help

Schema Reference #

The schema is a single JSON file requiring three sections: config, api.methods, and response.

Single-Response (one entity for the whole feature) #

{
  "config": { "bloc": true, "riverpod": false },
  "api": {
    "methods": {
      "getUser":    {},
      "updateUser": { "body": { "name": "string", "email": "string" } },
      "deleteUser": { "params": { "id": "int" } }
    }
  },
  "response": { "id": "int", "name": "string" }
}

Multi-Response (different entities per method) #

When different API methods return different types, define each response type by name and add a "response" key to each method that declares which type it returns.

{
  "config": { "bloc": true, "riverpod": false },
  "api": {
    "methods": {
      "getUser":      { "response": "user" },
      "postSomeData": { "body": { "name": "string", "email": "string" }, "response": "token" },
      "updateUser":   { "body": { "name": "string" }, "response": "user" },
      "deleteUser":   { "params": { "id": "int" } }
    }
  },
  "response": {
    "user":  { "id": 123, "name": "string", "email": "string" },
    "token": { "accessToken": "string", "refreshToken": "string", "tokenType": "string" }
  }
}

Multi-response rules:

  • Detection — if all top-level values in response are objects, multi-response mode is activated automatically. No extra flag needed.
  • Per-method binding — set "response": "<key>" on any method to link it to a named entity.
  • List returns — wrap the key in an array to return a list: "response": ["user"]Future<List<UserEntity>>.
  • Void methods — omit "response" entirely and the method generates Future<void> across all layers.
  • Backward compatible — schemas with primitive values at the top level of response continue to work as single-response.

Common Options #

  • config: Both keys (bloc and riverpod) are required; exactly one must be true.
  • api.methods: Define endpoints (camelCase). Optionally include params, body, or query to generate UseCase and param classes.
  • response: Define entity fields. Supported primitives: "string", "int", "double", "bool", "list", "map". Supports nested objects and arrays.

Generated Structure #

Running the CLI produces a complete clean-architecture module in lib/features/<feature_name>/:

lib/features/<feature>/
├── data/
│   ├── datasources/   <feature>_remote_datasource.dart
│   ├── models/        <entity>_model.dart          (one per entity in multi-response)
│   └── repositories/  <feature>_repository_impl.dart
└── domain/
    ├── entities/      <entity>_entity.dart          (one per entity in multi-response)
    ├── repositories/  <feature>_repository.dart
    └── usecases/      <method>_usecase.dart
└── presentation/
    ├── bloc/          <feature>_bloc.dart, _event.dart, _state.dart
    └── screen/        <feature>_screen.dart

In multi-response mode, the BLoC and Riverpod states get one typed success factory per method:

// generated user_state.dart
const factory UserState.getUserSuccess(UserEntity data) = _GetUserSuccessState;
const factory UserState.postSomeDataSuccess(TokenEntity data) = _PostSomeDataSuccessState;
const factory UserState.deleteUserSuccess() = _DeleteUserSuccessState;

The CLI automatically adds missing dependencies, runs build_runner, and formats the generated code.

Overwrite Behavior #

By default, the CLI only generates missing files and will not overwrite existing files. Use --overwrite (or -o) to force regeneration.

Troubleshooting #

  • Schema validation errors: Ensure config, api.methods, and response exist, and that exactly one of config.bloc or config.riverpod is true.
  • build_runner failed: Re-run it manually: dart run build_runner build -d.

Support ❤️ #

If you find this package helpful, please consider giving it a like on pub.dev and adding a ⭐ star on GitHub! Your support is greatly appreciated.

Contributing #

  • Install dependencies: dart pub get
  • Run tests: dart test
  • Format code: dart format .

Note: The test suite is pure unit tests and avoids running external commands.

License #

MIT