A comprehensive Laravel package that bridges your Laravel backend with Flutter frontend by automatically generating complete Flutter features (models, services, UI components) from your existing Laravel Eloquent models and routes.
- 🚀 Automatic Code Generation: Generate complete Flutter features from Laravel models
- 📱 UI Components: Create forms, lists, and detail views automatically
- 🔗 API Integration: Generate Flutter services that integrate with Laravel API endpoints
- 🏗️ SOLID Principles: Clean, maintainable code following best practices
- 🎨 Customizable Templates: Modify generation templates to fit your needs
- 🧪 Comprehensive Testing: Full test coverage for reliable code generation
- 🔄 CRUD Operations: Complete Create, Read, Update, Delete functionality
- 🎯 Type Safety: Full Dart null safety support
- 📊 Relationship Support: Handle Eloquent model relationships
- ⚡ Performance Optimized: Efficient code generation with minimal dependencies
Install the package via Composer:
composer require bashar-shaeb/laravel-flutter-generator
Publish the configuration file:
php artisan vendor:publish --provider="BasharShaeb\LaravelFlutterGenerator\FlutterGeneratorServiceProvider" --tag="flutter-generator-config"
Optionally, publish the templates for customization:
php artisan vendor:publish --provider="BasharShaeb\LaravelFlutterGenerator\FlutterGeneratorServiceProvider" --tag="flutter-generator-templates"
php artisan flutter:generate-model User
php artisan flutter:generate-service User --with-routes
php artisan flutter:generate-feature User
php artisan flutter:generate-all
php artisan flutter:generate-all --models=User,Post,Category
--force
: Overwrite existing files without confirmation--all
: Process all available models
--skip-model
: Skip model generation--skip-service
: Skip service generation--skip-widgets
: Skip widget generation--skip-screens
: Skip screen generation--with-routes
: Include route analysis for custom API methods
The package configuration file is published to config/flutter-generator.php
. Key configuration options:
'output' => [
'base_path' => base_path('flutter_output'),
'models_path' => 'models',
'services_path' => 'services',
'widgets_path' => 'widgets',
'screens_path' => 'screens',
],
'api' => [
'base_url' => env('FLUTTER_API_BASE_URL', 'http://localhost:8000/api'),
'timeout' => 30,
'authentication' => [
'type' => 'bearer', // bearer, basic, none
'header_name' => 'Authorization',
],
],
'generation' => [
'architecture' => 'provider', // provider, bloc, riverpod
'null_safety' => true,
'use_freezed' => false,
'use_json_annotation' => true,
'generate_tests' => true,
'generate_documentation' => true,
],
'model_analysis' => [
'include_relationships' => true,
'include_accessors' => true,
'include_timestamps' => true,
'excluded_attributes' => [
'password',
'remember_token',
'email_verified_at',
],
],
flutter_output/
├── models/
│ ├── user.dart
│ ├── user.g.dart (if using json_annotation)
│ └── post.dart
├── services/
│ ├── api_service.dart (base HTTP client)
│ ├── user_service.dart
│ └── post_service.dart
├── widgets/
│ ├── user_form.dart
│ ├── user_list.dart
│ ├── user_card.dart
│ └── post_form.dart
└── screens/
├── user_list_screen.dart
├── user_detail_screen.dart
├── user_create_screen.dart
└── user_edit_screen.dart
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';
@JsonSerializable()
class User {
final int id;
final String name;
final String email;
final DateTime? emailVerifiedAt;
final bool isActive;
const User({
required this.id,
required this.name,
required this.email,
this.emailVerifiedAt,
required this.isActive,
});
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
User copyWith({
int? id,
String? name,
String? email,
DateTime? emailVerifiedAt,
bool? isActive,
}) {
return User(
id: id ?? this.id,
name: name ?? this.name,
email: email ?? this.email,
emailVerifiedAt: emailVerifiedAt ?? this.emailVerifiedAt,
isActive: isActive ?? this.isActive,
);
}
}
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/user.dart';
import 'api_service.dart';
class UserService {
final ApiService _apiService;
final String _endpoint;
UserService(this._apiService, this._endpoint);
Future<List<User>> getAll({int? page, Map<String, dynamic>? filters}) async {
try {
final queryParams = <String, String>{};
if (page != null) queryParams['page'] = page.toString();
final response = await _apiService.get(_endpoint, queryParams: queryParams);
final List<dynamic> data = response['data'] ?? response;
return data.map((json) => User.fromJson(json)).toList();
} catch (e) {
throw Exception('Failed to fetch User list: $e');
}
}
Future<User> getById(int id) async {
try {
final response = await _apiService.get('$_endpoint/$id');
final data = response['data'] ?? response;
return User.fromJson(data);
} catch (e) {
throw Exception('Failed to fetch User with ID $id: $e');
}
}
Future<User> create(Map<String, dynamic> data) async {
try {
final response = await _apiService.post(_endpoint, data);
final responseData = response['data'] ?? response;
return User.fromJson(responseData);
} catch (e) {
throw Exception('Failed to create User: $e');
}
}
Future<User> update(int id, Map<String, dynamic> data) async {
try {
final response = await _apiService.put('$_endpoint/$id', data);
final responseData = response['data'] ?? response;
return User.fromJson(responseData);
} catch (e) {
throw Exception('Failed to update User with ID $id: $e');
}
}
Future<bool> delete(int id) async {
try {
await _apiService.delete('$_endpoint/$id');
return true;
} catch (e) {
throw Exception('Failed to delete User with ID $id: $e');
}
}
}
- Copy generated files to your Flutter project:
cp -r flutter_output/* your_flutter_project/lib/
- Add dependencies to your
pubspec.yaml
:
dependencies:
flutter:
sdk: flutter
http: ^1.1.0
json_annotation: ^4.8.1
provider: ^6.1.1 # if using Provider architecture
dev_dependencies:
build_runner: ^2.4.7
json_serializable: ^6.7.1
- Run code generation (if using json_annotation):
flutter packages pub run build_runner build
- Initialize API service in your app:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: UserListScreen(),
);
}
}
You can customize the generated code by modifying the published templates in resources/views/flutter-generator/
.
Add models to exclude in your configuration:
'excluded_models' => [
'App\\Models\\InternalModel',
'Spatie\\Permission\\Models\\Role',
],
Use the --with-routes
flag to analyze your API routes and generate additional service methods:
php artisan flutter:generate-service User --with-routes
This will analyze routes like:
GET /api/users/{user}/posts
→getUserPosts(int userId)
POST /api/users/{user}/activate
→activateUser(int userId)
Run the package tests:
composer test
Run with coverage:
composer test-coverage
- PHP 8.1+ (8.2, 8.3, 8.4 supported)
- Laravel 10.0+, 11.0+, or 12.0+
- Flutter 3.0+
- Doctrine DBAL 3.0+ or 4.0+ (for database schema analysis)
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
BasharShaeb - GitHub Profile
See CHANGELOG.md for a list of changes.
This package is open-sourced software licensed under the MIT license.