flutist 1.0.9
flutist: ^1.0.9 copied to clipboard
A Flutter project management framework inspired by Tuist
📋 Table of Contents #
- About
- Installation
- Features
- Quick Start
- Commands
- Project Structure
- Configuration Files
- Module Types
- Scaffold Templates
- Dependency Management
- Code Generation
- Examples
- Contributing
- License
🎯 About #
Flutist is a powerful project management framework for Flutter applications, inspired by Tuist for iOS development. It provides a structured approach to managing large-scale Flutter projects with modular architecture, centralized dependency management, and code generation capabilities.
🚀 Core Commands #
The main commands you'll use most frequently:
flutist init #
Initialize a new Flutist project with workspace support. Creates all configuration files and sets up the project structure.
flutist create #
Create new modules (feature, library, standard, simple) with predefined architectures.
flutist generate #
Sync all pubspec.yaml files based on project.dart and regenerate flutist_gen.dart.
flutist scaffold #
Generate code from user-defined templates. Create boilerplate code quickly with custom templates.
📋 All Commands #
| Command | Description | Usage |
|---|---|---|
init |
Initialize a new Flutist project | flutist init |
create |
Create a new module | flutist create --path <path> --name <name> --options <type> |
generate |
Sync dependencies and regenerate files | flutist generate |
scaffold |
Generate code from templates | flutist scaffold <template> --name <name> |
run |
Run the Flutter app | flutist run [options] |
pub |
Manage dependencies | flutist pub add <package> |
graph |
Visualize module dependencies | flutist graph [--format <format>] |
help |
Show help information | flutist help [command] |
For detailed information about each command, see the Commands section below.
📦 Installation #
Prerequisites #
- Dart SDK (>=3.5.0 <4.0.0)
Install Flutist #
dart pub global activate flutist
Why Flutist? #
- 🏗️ Modular Architecture: Organize your codebase into clear, reusable modules
- 📦 Centralized Dependencies: Manage all dependencies in one place
- 🚀 Fast Development: Generate boilerplate code with scaffold templates
- 🔗 Dependency Visualization: Visualize module dependencies with graphs
- ⚡ Workspace Support: Leverage Flutter's native workspace feature
- 🎨 Code Generation: Create custom templates for rapid development
✨ Features #
- Workspace Management: Native Flutter workspace support for multi-package projects
- Module Creation: Create modules with predefined structures (feature, library, standard, simple)
- Dependency Sync: Automatically sync dependencies across all modules
- Code Scaffolding: Generate code from custom templates
- Dependency Graphs: Visualize module dependencies in multiple formats
- Type-Safe Configuration: Dart-based configuration files with IDE support
- Code Generation: Auto-generate helper code for easy dependency access
🚀 Quick Start #
1. Initialize a New Project #
# Navigate to your project directory
cd my_flutter_project
# Initialize Flutist
flutist init
This command will:
- Create
project.dartandpackage.dartconfiguration files - Set up
pubspec.yamlwith workspace configuration - Create a default
appmodule - Generate example scaffold templates
- Create
flutist_gen.dartfor code generation
2. Create a Module #
# Create a feature module
flutist create --path features --name login --options feature
# Create a simple module
flutist create --path lib --name utils --options simple
3. Sync Dependencies #
# Add a dependency to package.dart
flutist pub add http
# Sync dependencies to all modules
flutist generate
4. Generate Code from Templates #
# List available templates
flutist scaffold list
# Generate code from a template
flutist scaffold feature --name login
5. Run Your App #
flutist run
🛠️ Commands #
Detailed documentation for all Flutist commands.
flutist init #
Initialize a new Flutist project with Workspace support.
Usage:
flutist init
What it does:
- Creates
project.dart- Project configuration file - Creates
package.dart- Centralized dependency management - Sets up
pubspec.yaml- Workspace configuration - Creates
analysis_options.yaml- Linting rules - Creates
README.md- Project documentation - Creates default
appmodule - Generates example scaffold templates in
flutist/templates/ - Generates
flutist/flutist_gen.dart- Code generation helpers
Example:
flutist init
Generated Structure:
my_project/
├── project.dart
├── package.dart
├── pubspec.yaml
├── analysis_options.yaml
├── README.md
├── app/
│ ├── lib/
│ │ ├── main.dart
│ │ └── app.dart
│ └── pubspec.yaml
└── flutist/
├── templates/
│ └── feature/
│ ├── template.yaml
│ ├── bloc.dart.template
│ ├── state.dart.template
│ ├── event.dart.template
│ └── screen.dart.template
└── flutist_gen.dart
flutist create #
Create a new module in the Flutist project.
Usage:
flutist create --path <path> --name <name> --options <type>
Options:
--path, -p <path>- Directory path where the module will be created (required)--name, -n <name>- Name of the module (required)--options, -o <type>- Module type:feature,library,standard,simple(required)
Module Types:
-
feature - Feature module with 3-layer architecture:
{name}_domain- Domain layer (business logic){name}_data- Data layer (repositories, data sources){name}_presentation- Presentation layer (UI, state management)
-
library - Library module with 5-layer architecture:
{name}_example- Example usage and demos{name}_interface- Public API and contracts{name}_implementation- Core implementation{name}_testing- Test utilities and mocks{name}_tests- Unit and widget tests
-
standard - Standard module with 3-layer architecture:
{name}_implementation- Core functionality{name}_tests- Unit and integration tests{name}_testing- Test utilities and helpers
-
simple - Simple module with minimal structure:
lib/- Source code directory
Examples:
# Create a feature module
flutist create --path features --name login --options feature
# Create a library module
flutist create --path lib --name network --options library
# Create a standard module
flutist create --path core --name models --options standard
# Create a simple module
flutist create --path lib --name utils --options simple
# Using short flags
flutist create -p features -n authentication -o feature
What it does:
- Creates module directory structure based on type
- Generates
pubspec.yamlfor each layer - Creates
lib/folders - Generates
analysis_options.yamlthat includes root config - Updates root
pubspec.yamlworkspace - Updates
project.dartwith new module entries - Updates
package.dartwith new module entries - Generates
README.mdfor the module
flutist generate #
Sync all pubspec.yaml files based on project.dart.
Usage:
flutist generate
What it does:
- Parses
package.dartto get all available dependencies - Parses
project.dartto get module configurations - Updates each module's
pubspec.yamlwith correct dependencies - Calculates relative paths for module dependencies
- Regenerates
flutist_gen.dartwith latest module and dependency information
When to use:
- After modifying
project.dartorpackage.dart - After adding new dependencies with
flutist pub add - After creating new modules
- When dependencies are out of sync
Example:
flutist generate
Output:
🔹 Starting Flutist generation...
✅ Parsed package.dart
Dependencies: 5
Modules: 3
✅ Generated flutist_gen.dart
✅ Parsed project.dart
Modules: 3
🔹 Updating pubspec.yaml files...
✅ Updated app
✅ Updated login_domain
✅ Updated login_data
✅ Updated login_presentation
✅ Generation completed!
flutist run #
Run the Flutter app from root/app/main.dart.
Usage:
flutist run [flutter_run_arguments]
Description:
Runs your Flutter application from the root directory. All arguments are passed directly to flutter run.
Examples:
# Run in debug mode
flutist run
# Run in release mode
flutist run --release
# Run on specific device
flutist run -d chrome
flutist run -d ios
# Run with additional flags
flutist run --debug --verbose
What it does:
- Checks if
appdirectory exists - Verifies
app/lib/main.dartexists - Creates root
lib/main.dartif it doesn't exist (imports app module) - Executes
flutter runfrom root directory (Flutter workspace automatically findsapp/lib/main.dart)
flutist pub #
Manage dependencies in package.dart.
Usage:
flutist pub add <package_name> [--version <version>]
Subcommands:
add <package>- Add a new dependency topackage.dart
Options:
--version <version>- Specify package version (optional, defaults to latest)
What it does:
- Fetches the latest version of the package using
dart pub add - Adds the dependency to
package.dart - Regenerates
flutist_gen.dartwith the new dependency
Examples:
# Add a package (auto-detects latest version)
flutist pub add http
# Add a package with specific version
flutist pub add provider --version ^2.0.0
# Add multiple packages
flutist pub add dio
flutist pub add bloc
flutist pub add flutter_bloc
After adding dependencies:
# Sync dependencies to all modules
flutist generate
flutist scaffold #
Generate code from user-defined templates.
Usage:
flutist scaffold <template> --name <name> [options]
flutist scaffold list
flutist scaffold help [subcommand]
Subcommands:
list- Lists all available scaffold templateshelp <subcommand>- Show help for a specific subcommand
Options:
--name <name>- Name for the generated files (required)--path <path>- Output path (default: current directory)-h, --help- Show help information
Template Structure:
flutist/templates/
feature/
template.yaml # Template configuration
bloc.dart.template # Template file with {{name}} variables
state.dart.template
event.dart.template
screen.dart.template
Template Variables:
{{name}}- snake_case (e.g.,user_profile){{Name}}- PascalCase (e.g.,UserProfile){{NAME}}- UPPER_CASE (e.g.,USER_PROFILE){{custom}}- Custom attributes fromtemplate.yaml
Examples:
# List available templates
flutist scaffold list
# Generate from template
flutist scaffold feature --name login
# Generate with custom path
flutist scaffold feature --name user_profile --path lib/features
# Generate with custom attributes
flutist scaffold feature --name auth --basePath lib/features
Template Configuration (template.yaml):
description: "Feature template with BLoC pattern"
attributes:
- name: name
required: true
- name: path
required: false
default: "lib/features"
items:
- type: file
path: "{{path}}/{{name}}/{{name}}_bloc.dart"
templatePath: "bloc.dart.template"
- type: file
path: "{{path}}/{{name}}/{{name}}_state.dart"
templatePath: "state.dart.template"
- type: directory
path: "{{path}}/{{name}}/assets"
sourcePath: "assets"
Simple Mode:
If template.yaml doesn't exist, Flutist will process all .template files in the template directory:
flutist/templates/
my_template/
component.dart.template
widget.dart.template
flutist graph #
Generate dependency graph of modules.
Usage:
flutist graph [options]
Options:
-f, --format <format>- Output format:mermaid,dot,ascii(default:mermaid)-o, --output <path>- Output file path (for mermaid/dot formats)--open- Open in browser (mermaid only)-h, --help- Show help information
Formats:
- mermaid - Mermaid diagram format (for documentation, GitHub, etc.)
- dot - Graphviz DOT format (for visualization tools)
- ascii - ASCII art representation (for terminal)
Examples:
# Generate mermaid diagram (default)
flutist graph
# Generate and save to file
flutist graph --format mermaid --output graph.mmd
# Generate and open in browser
flutist graph --format mermaid --open
# Generate Graphviz DOT format
flutist graph --format dot --output graph.dot
# Generate ASCII art
flutist graph --format ascii
What it does:
- Parses
project.dartto extract module structure - Analyzes module dependencies
- Generates dependency graph in specified format
- Optionally saves to file or opens in browser
Example Output (Mermaid):
graph TD
app --> login_presentation
login_presentation --> login_data
login_data --> login_domain
app --> user_domain
flutist help #
Display help information for Flutist commands.
Usage:
flutist help
flutist help <command>
Examples:
# Show general help
flutist help
# Show help for specific command
flutist help create
flutist help scaffold
flutist help graph
📁 Project Structure #
A typical Flutist project has the following structure:
my_project/
├── project.dart # Project configuration
├── package.dart # Centralized dependencies
├── pubspec.yaml # Workspace configuration
├── analysis_options.yaml # Linting rules
├── README.md # Project documentation
├── app/ # Main application module
│ ├── lib/
│ │ ├── main.dart
│ │ └── app.dart
│ └── pubspec.yaml
├── features/ # Feature modules
│ └── login/
│ ├── login_domain/
│ ├── login_data/
│ └── login_presentation/
├── core/ # Core modules
│ └── models/
│ ├── models_implementation/
│ ├── models_tests/
│ └── models_testing/
├── lib/ # Simple modules
│ └── utils/
│ └── lib/
└── flutist/
├── templates/ # Scaffold templates
│ └── feature/
└── flutist_gen.dart # Generated code
⚙️ Configuration Files #
project.dart #
The project.dart file defines the entire project structure with all modules and their dependencies.
Location: Root directory
Structure:
import 'package:flutist/flutist.dart';
import 'flutist/flutist_gen.dart';
import 'package.dart';
final project = Project(
name: 'my_project',
options: const ProjectOptions(),
modules: [
Module(
name: 'app',
type: ModuleType.simple,
dependencies: [
package.dependencies.http,
package.dependencies.dio,
],
devDependencies: [
package.dependencies.test,
],
modules: [
package.modules.login,
package.modules.user,
],
),
Module(
name: 'login',
type: ModuleType.feature,
dependencies: [
package.dependencies.bloc,
],
modules: [
package.modules.user_domain,
],
),
],
);
Key Points:
- Uses
package.dependencies.xxxto reference dependencies frompackage.dart - Uses
package.modules.xxxto reference other modules - Defines module structure and relationships
- Used by
flutist generateto syncpubspec.yamlfiles
package.dart #
The package.dart file is the central repository for all dependencies and module definitions.
Location: Root directory
Structure:
import 'package:flutist/flutist.dart';
final package = Package(
name: 'my_project',
dependencies: [
Dependency(name: 'http', version: '^1.0.0'),
Dependency(name: 'dio', version: '^5.0.0'),
Dependency(name: 'bloc', version: '^8.0.0'),
Dependency(name: 'test', version: '^1.28.0'),
],
modules: [
Module(name: 'app', type: ModuleType.simple),
Module(name: 'login', type: ModuleType.feature),
Module(name: 'user_domain', type: ModuleType.standard),
],
);
Key Points:
- Central location for all package dependencies
- Defines all modules in the workspace
- Used to generate
flutist_gen.dartfor type-safe access - Add dependencies using
flutist pub add <package>
Accessing Dependencies:
After running flutist generate, you can access dependencies using generated getters:
import 'flutist/flutist_gen.dart';
import 'package.dart';
// Access dependencies
final httpDep = package.dependencies.http;
final blocDep = package.dependencies.bloc;
// Access modules
final loginModule = package.modules.login;
final appModule = package.modules.app;
pubspec.yaml #
The root pubspec.yaml file configures the Flutter workspace.
Location: Root directory
Structure:
name: my_project
description: A new Flutter project managed by Flutist.
version: 1.0.0+1
publish_to: 'none'
environment:
sdk: ">=3.5.0 <4.0.0"
dependencies:
flutter:
sdk: flutter
flutist:
path: ../flutist
# Flutter Native Workspace configuration
workspace:
- app
- features/login/login_domain
- features/login/login_data
- features/login/login_presentation
Key Points:
- Uses Flutter's native workspace feature
- Lists all modules in the workspace
- Automatically updated when creating modules
- Each module has its own
pubspec.yaml
🏗️ Module Types #
Feature Module #
A feature module follows Clean Architecture with 3 layers:
login/
├── login_domain/ # Business logic, entities
│ └── lib/
├── login_data/ # Data sources, repositories
│ └── lib/
└── login_presentation/ # UI, state management
└── lib/
Use cases:
- User-facing features (login, profile, settings)
- Features with complex business logic
- Features requiring separation of concerns
Example:
flutist create --path features --name authentication --options feature
Library Module #
A library module provides reusable code with 5 layers:
network/
├── network_example/ # Example usage
│ └── lib/
├── network_interface/ # Public API
│ └── lib/
├── network_implementation/ # Core implementation
│ └── lib/
├── network_testing/ # Test utilities
│ └── lib/
└── network_tests/ # Unit tests
└── lib/
Use cases:
- Reusable libraries
- Shared utilities
- Packages that need examples
- Libraries with comprehensive testing
Example:
flutist create --path lib --name network --options library
Standard Module #
A standard module with 3 layers:
models/
├── models_implementation/ # Core functionality
│ └── lib/
├── models_tests/ # Unit tests
│ └── lib/
└── models_testing/ # Test utilities
└── lib/
Use cases:
- Domain models
- Data models
- Shared business logic
- Modules requiring testing
Example:
flutist create --path core --name models --options standard
Simple Module #
A simple module with minimal structure:
utils/
└── lib/ # Source code
Use cases:
- Simple utility modules
- App module
- Modules without complex structure
- Quick prototypes
Example:
flutist create --path lib --name utils --options simple
🎨 Scaffold Templates #
Scaffold templates allow you to generate boilerplate code from custom templates.
Creating a Template #
- Create template directory:
mkdir -p flutist/templates/my_template
- Create template.yaml (optional):
description: "My custom template"
attributes:
- name: name
required: true
- name: path
required: false
default: "lib/features"
items:
- type: file
path: "{{path}}/{{name}}/{{name}}_service.dart"
templatePath: "service.dart.template"
- type: file
path: "{{path}}/{{name}}/{{name}}_repository.dart"
templatePath: "repository.dart.template"
- Create template files:
// service.dart.template
class {{Name}}Service {
// Service implementation for {{name}}
}
Template Variables #
Templates support variable substitution:
{{name}}- snake_case:user_profile{{Name}}- PascalCase:UserProfile{{NAME}}- UPPER_CASE:USER_PROFILE{{name_camel}}- camelCase:userProfile{{custom}}- Custom attributes fromtemplate.yaml
Using Templates #
# List available templates
flutist scaffold list
# Generate from template
flutist scaffold my_template --name user_service
# With custom attributes
flutist scaffold my_template --name auth --path lib/services
Example: Feature Template #
The default feature template generates BLoC pattern code:
flutist scaffold feature --name login
Generates:
login_bloc.dart- BLoC implementationlogin_state.dart- State classeslogin_event.dart- Event classeslogin_screen.dart- UI screen
📦 Dependency Management #
Adding Dependencies #
Using Flutist CLI:
flutist pub add http
flutist pub add bloc --version ^8.0.0
Manually in package.dart:
final package = Package(
name: 'my_project',
dependencies: [
Dependency(name: 'http', version: '^1.0.0'),
Dependency(name: 'bloc', version: '^8.0.0'),
// ... more dependencies
],
modules: [...],
);
Using Dependencies in Modules #
In project.dart:
Module(
name: 'login',
type: ModuleType.feature,
dependencies: [
package.dependencies.http, // Reference from package.dart
package.dependencies.bloc,
],
devDependencies: [
package.dependencies.test,
],
modules: [
package.modules.user_domain, // Reference other modules
],
)
Syncing Dependencies #
After modifying dependencies, sync them:
flutist generate
This will:
- Update all module
pubspec.yamlfiles - Calculate relative paths for module dependencies
- Regenerate
flutist_gen.dart
🔧 Code Generation #
flutist_gen.dart #
Flutist automatically generates flutist/flutist_gen.dart with type-safe getters for dependencies and modules.
Generated Code:
// GENERATED CODE - DO NOT MODIFY BY HAND
// Generated by Flutist
import 'package:flutist/flutist.dart';
/// Extension for package.dependencies.xxx access
extension PackageDependenciesX on List<Dependency> {
/// Dependency getter for http
Dependency get http => firstWhere((d) => d.name == 'http');
/// Dependency getter for bloc
Dependency get bloc => firstWhere((d) => d.name == 'bloc');
}
/// Extension for package.modules.xxx access
extension PackageModulesX on List<Module> {
/// Module getter for app
Module get app => firstWhere((m) => m.name == 'app');
/// Module getter for login
Module get login => firstWhere((m) => m.name == 'login');
}
Usage:
import 'flutist/flutist_gen.dart';
import 'package.dart';
// Type-safe access
final httpDep = package.dependencies.http;
final loginModule = package.modules.login;
Regeneration: The file is automatically regenerated when:
- Running
flutist generate - Running
flutist create - Running
flutist pub add - Running
flutist init
📚 Examples #
Complete Workflow Example #
# 1. Initialize project
flutist init
# 2. Add dependencies
flutist pub add http
flutist pub add bloc
flutist pub add flutter_bloc
# 3. Create modules
flutist create --path features --name login --options feature
flutist create --path core --name models --options standard
flutist create --path lib --name utils --options simple
# 4. Configure dependencies in project.dart
# Edit project.dart to add dependencies to modules
# 5. Sync everything
flutist generate
# 6. Generate code from template
flutist scaffold feature --name user_profile
# 7. Run the app
flutist run
Feature Module Example #
Creating a login feature:
flutist create --path features --name login --options feature
Structure created:
features/
└── login/
├── login_domain/
│ ├── lib/
│ └── pubspec.yaml
├── login_data/
│ ├── lib/
│ └── pubspec.yaml
└── login_presentation/
├── lib/
└── pubspec.yaml
Configuring in project.dart:
Module(
name: 'login',
type: ModuleType.feature,
dependencies: [
package.dependencies.bloc,
package.dependencies.http,
],
modules: [
package.modules.user_domain,
],
)
Library Module Example #
Creating a network library:
flutist create --path lib --name network --options library
Structure created:
lib/
└── network/
├── network_example/
│ ├── lib/
│ │ └── main.dart
│ └── pubspec.yaml
├── network_interface/
│ ├── lib/
│ └── pubspec.yaml
├── network_implementation/
│ ├── lib/
│ └── pubspec.yaml
├── network_testing/
│ ├── lib/
│ └── pubspec.yaml
└── network_tests/
├── lib/
└── pubspec.yaml
Scaffold Template Example #
Creating a custom template:
- Create template structure:
mkdir -p flutist/templates/repository
- Create
template.yaml:
description: "Repository pattern template"
attributes:
- name: name
required: true
items:
- type: file
path: "lib/repositories/{{name}}_repository.dart"
templatePath: "repository.dart.template"
- type: file
path: "lib/repositories/{{name}}_repository_impl.dart"
templatePath: "repository_impl.dart.template"
- Create
repository.dart.template:
abstract class {{Name}}Repository {
Future<List<{{Name}}>> getAll();
Future<{{Name}}?> getById(String id);
}
- Create
repository_impl.dart.template:
class {{Name}}RepositoryImpl implements {{Name}}Repository {
@override
Future<List<{{Name}}>> getAll() {
// Implementation
}
@override
Future<{{Name}}?> getById(String id) {
// Implementation
}
}
- Use the template:
flutist scaffold repository --name user
Dependency Graph Example #
Generate and view dependency graph:
# Generate mermaid diagram
flutist graph --format mermaid --output docs/dependency-graph.mmd
# Generate and open in browser
flutist graph --format mermaid --open
# Generate ASCII art for terminal
flutist graph --format ascii
🤝 Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup #
- Clone the repository:
git clone https://github.com/yourusername/flutist.git
cd flutist
- Install dependencies:
dart pub get
- Run tests:
dart test
- Make your changes and test:
# Test locally
dart run bin/flutist.dart <command>
Code Style #
- Follow Dart style guidelines
- Use meaningful variable and function names
- Add comments for complex logic
- Write tests for new features
📄 License #
This project is licensed under the MIT License.
🔗 Resources #
Built with ❤️ for the Flutter community