Clean Architecture Flutter Project Setup Guide 
This is a complete, stepโbyโstep guide that collects all the pieces of our Clean Architecture Flutter project. This document is designed to help our team set up the project with theming, responsiveness, localization (using easy_localization), state management (BLoC & Provider), and automation scriptsโall while maintaining code quality with strict linter rules and Git hooks. Enjoy the ride!
Table of Contents
- Project Overview & Folder Structure
- Dependencies & pubspec.yaml Setup
- Core Modules Setup
- Main Application Setup (main.dart)
- Sample Home Screen (home_screen.dart)
- Module Scaffolding Shell Script
- Git Hooks & Linter Configuration
- Final Thoughts
1. Project Overview & Folder Structure 
Our project is structured according to Clean Architecture principles. Each feature has its own sub-folders for data, domain, and presentation layers. Additionally, we have a core folder for shared utilities such as theme, responsiveness, and localization.
my_flutter_app/ โโโ assets/ โ โโโ translations/ โ โโโ en.json โ โโโ es.json โโโ lib/ โ โโโ core/ โ โ โโโ responsive/ โ โ โ โโโ responsive.dart โ โ โโโ theme/ โ โ โ โโโ app_theme.dart โ โ โโโ utils/ โ โโโ features/ โ โ โโโ feature_name/ # Replace with your module/feature name โ โ โโโ data/ โ โ โ โโโ datasources/ โ โ โ โโโ models/ โ โ โ โโโ repositories/ โ โ โโโ domain/ โ โ โ โโโ entities/ โ โ โ โโโ repositories/ โ โ โ โโโ usecases/ โ โ โโโ presentation/ โ โ โโโ screens/ โ โ โ โโโ home_screen.dart โ โ โโโ widgets/ โ โ โโโ bloc/ # For BLoC-based state management โ โ โโโ provider/ # For Provider-based state management โ โโโ main.dart โโโ analysis_options.yaml โโโ setup_project.sh # Shell script to scaffold folders & files
2. Dependencies & pubspec.yaml Setup 
Update your pubspec.yaml
to include the necessary dependencies:
name: my_flutter_app description: A Flutter app using Clean Architecture with easy_localization. environment: sdk: ">=2.17.0 <3.0.0" dependencies: flutter: sdk: flutter easy_localization: ^3.0.0 flutter_bloc: ^8.0.0 # (Optional: For BLoC state management) provider: ^6.0.0 # (Optional: For Provider state management) dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true # Specify the directory for your translation files assets: - assets/translations/
3. Core Modules Setup 
Theme (app_theme.dart) 
Create lib/core/theme/app_theme.dart
with the following content:
import 'package:flutter/material.dart'; class AppTheme { /// Returns the light theme configuration. static ThemeData lightTheme() { return ThemeData( primarySwatch: Colors.blue, brightness: Brightness.light, visualDensity: VisualDensity.adaptivePlatformDensity, // Add additional light theme settings (fonts, icon themes, etc.) ); } /// Returns the dark theme configuration. static ThemeData darkTheme() { return ThemeData( primarySwatch: Colors.blue, brightness: Brightness.dark, visualDensity: VisualDensity.adaptivePlatformDensity, // Add additional dark theme settings ); } }
Responsive (responsive.dart) 
Create lib/core/responsive/responsive.dart
with the following content:
import 'package:flutter/material.dart'; class Responsive { final BuildContext context; Responsive(this.context); /// Returns the screen width. double get width => MediaQuery.of(context).size.width; /// Returns the screen height. double get height => MediaQuery.of(context).size.height; /// Returns true if the device is mobile (width < 600). bool get isMobile => width < 600; /// Returns true if the device is a tablet (600 <= width < 1100). bool get isTablet => width >= 600 && width < 1100; /// Returns true if the device is desktop (width >= 1100). bool get isDesktop => width >= 1100; /// Returns a width percentage (e.g., 50% of the screen width). double wp(double percentage) => width * percentage / 100; /// Returns a height percentage (e.g., 50% of the screen height). double hp(double percentage) => height * percentage / 100; }
Localization with easy_localization 
1. Translation Files: Create the folder assets/translations/
and add your JSON translation files.
assets/translations/en.json:
{ "title": "Clean Architecture Flutter App", "home_screen": "Home Screen", "welcome_message": "Welcome to our app!" }
assets/translations/es.json:
{ "title": "Aplicaciรณn Flutter de Arquitectura Limpia", "home_screen": "Pantalla Principal", "welcome_message": "ยกBienvenido a nuestra aplicaciรณn!" }
No additional code is needed for easy_localizationโthe configuration is done in main.dart
(see below).
4. Main Application Setup (main.dart) 
Create or update lib/main.dart
:
import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import 'core/theme/app_theme.dart'; import 'features/feature_name/presentation/screens/home_screen.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); runApp( EasyLocalization( supportedLocales: const [Locale('en'), Locale('es')], path: 'assets/translations', // Path to your translations folder fallbackLocale: const Locale('en'), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: tr('title'), debugShowCheckedModeBanner: false, theme: AppTheme.lightTheme(), darkTheme: AppTheme.darkTheme(), // Dynamically switch themes based on system settings themeMode: ThemeMode.system, localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, home: const HomeScreen(), ); } }
5. Sample Home Screen (home_screen.dart) 
Create lib/features/feature_name/presentation/screens/home_screen.dart
:
import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; import '../../../core/responsive/responsive.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context) { final responsive = Responsive(context); return Scaffold( appBar: AppBar( title: Text(tr('home_screen')), ), body: Center( child: Padding( padding: EdgeInsets.all(responsive.wp(5)), // 5% of screen width as padding child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( tr('welcome_message'), style: TextStyle(fontSize: responsive.wp(5)), // Responsive font size textAlign: TextAlign.center, ), const SizedBox(height: 20), Text( 'Screen width: ${responsive.width.toStringAsFixed(2)}', style: TextStyle(fontSize: responsive.wp(4)), ), Text( 'Screen height: ${responsive.height.toStringAsFixed(2)}', style: TextStyle(fontSize: responsive.wp(4)), ), Text( 'Is Mobile: ${responsive.isMobile}', style: TextStyle(fontSize: responsive.wp(4)), ), ], ), ), ), ); } }
6. Module Scaffolding Shell Script 
To automate the creation of base folders and starter files (including our theme and responsive files), create a shell script named setup_project.sh
in the project root:
#!/bin/bash # ------------------------------ # SETUP PROJECT STRUCTURE SCRIPT # ------------------------------ # # This script creates the base folder structure in the "lib" directory, # including core folders and files for theme and responsive utilities. # # Optionally, if you pass a module name as an argument, it will also scaffold # the folder structure for that feature/module. # # Usage: # ./setup_project.sh [ModuleName] # # Example: # ./setup_project.sh user_profile # # ------------------------------ # Create base core directories echo "Creating core folders..." mkdir -p lib/core/theme mkdir -p lib/core/responsive # Create features folder if it doesn't exist mkdir -p lib/features # Create basic theme file with starter content echo "
Creating lib/core/theme/app_theme.dart..." cat << 'EOF' > lib/core/theme/app_theme.dart import 'package:flutter/material.dart'; class AppTheme { /// Returns the light theme configuration. static ThemeData lightTheme() { return ThemeData( primarySwatch: Colors.blue, brightness: Brightness.light, visualDensity: VisualDensity.adaptivePlatformDensity, // Add other light theme configurations (fonts, icon themes, etc.) ); } /// Returns the dark theme configuration. static ThemeData darkTheme() { return ThemeData( primarySwatch: Colors.blue, brightness: Brightness.dark, visualDensity: VisualDensity.adaptivePlatformDensity, // Add other dark theme configurations ); } } EOF # Create basic responsive file with starter content echo "
Creating lib/core/responsive/responsive.dart..." cat << 'EOF' > lib/core/responsive/responsive.dart import 'package:flutter/material.dart'; class Responsive { final BuildContext context; Responsive(this.context); /// Returns the screen width. double get width => MediaQuery.of(context).size.width; /// Returns the screen height. double get height => MediaQuery.of(context).size.height; /// Determines if the device is mobile. bool get isMobile => width < 600; /// Determines if the device is a tablet. bool get isTablet => width >= 600 && width < 1100; /// Determines if the device is a desktop. bool get isDesktop => width >= 1100; /// Returns width as a percentage of the total screen width. double wp(double percentage) => width * percentage / 100; /// Returns height as a percentage of the total screen height. double hp(double percentage) => height * percentage / 100; } EOF # Optional: If a module name is provided, scaffold the module structure. if [ -n "$1" ]; then MODULE_NAME=$1 echo "
Creating module structure for: $MODULE_NAME ..." # Create the feature base directory mkdir -p lib/features/$MODULE_NAME # Create Data Layer folders mkdir -p lib/features/$MODULE_NAME/data/datasources mkdir -p lib/features/$MODULE_NAME/data/models mkdir -p lib/features/$MODULE_NAME/data/repositories # Create Domain Layer folders mkdir -p lib/features/$MODULE_NAME/domain/entities mkdir -p lib/features/$MODULE_NAME/domain/repositories mkdir -p lib/features/$MODULE_NAME/domain/usecases # Create Presentation Layer folders mkdir -p lib/features/$MODULE_NAME/presentation/screens mkdir -p lib/features/$MODULE_NAME/presentation/widgets mkdir -p lib/features/$MODULE_NAME/presentation/bloc mkdir -p lib/features/$MODULE_NAME/presentation/provider echo "
Module '$MODULE_NAME' structure created successfully." fi echo "
Project structure created with basic theme and responsive files."
7. Git Hooks & Linter Configuration 
To enforce code quality, add a strict analysis_options.yaml
and set up a Git pre-commit hook.
analysis_options.yaml
# analysis_options.yaml include: package:flutter_lints/flutter.yaml analyzer: strong-mode: true errors: missing_return: error avoid_print: error linter: rules: always_declare_return_types: true always_specify_types: true avoid_empty_else: true avoid_init_to_null: true avoid_null_checks_in_equality_operators: true prefer_const_constructors: true prefer_const_literals_to_create_immutables: true use_key_in_widget_constructors: true
Git Pre-commit Hook
Create a file named pre-commit
in the .git/hooks/
directory with the following content:
#!/bin/sh # .git/hooks/pre-commit echo "Running flutter analyze..." flutter analyze RESULT=$? if [ $RESULT -ne 0 ]; then echo "
Linting issues found. Please resolve them before committing." exit 1 fi exit 0
Then make it executable:
chmod +x .git/hooks/pre-commit
8. Final Thoughts 
Architecture & Structure: Our Clean Architecture setup separates concerns into core, features, domain, and data layersโmaking the project scalable and maintainable.
Core Utilities: With pre-built theming, responsiveness, and localization (using easy_localization), our app will have consistent styling and support multiple languages out of the box.
Automation & Quality: The provided shell script accelerates module creation, and our linter & Git hook setup enforce strict code quality.
State Management: Both BLoC and Provider have been integrated (in main.dart
) so you can choose the best solution per feature.
Letโs work together to build a robust, scalable, and maintainable Flutter application! Happy coding!
This document should serve as the single source of truth for setting up new Flutter projects within our team. If you have any questions or suggestions, please reach out!