Skip to content

Project Structure

Understand the folder structure of a Flutter project.


What is it?

A Flutter project structure is the organized layout of folders and files that make up a Flutter application. It includes configuration files, platform-specific folders, source code, and assets. Understanding this structure is essential for navigating and maintaining Flutter projects.


Why does it exist?

Project structure exists to:

  • Organize code in a predictable way
  • Separate platform-specific code
  • Manage dependencies and configurations
  • Store assets like images and fonts
  • Support different build environments
  • Enable tooling and build systems
  • Maintain consistency across projects

Root Directory Structure

The root directory contains configuration files and the main folders for your Flutter app.

my_flutter_app/
├── android/          # Android platform-specific code
├── ios/              # iOS platform-specific code
├── lib/              # Main source code (Dart files)
├── test/             # Unit and widget tests
├── web/              # Web platform-specific code
├── windows/          # Windows platform-specific code
├── macos/            # macOS platform-specific code
├── linux/            # Linux platform-specific code
├── build/            # Generated build output
├── .dart_tool/       # Dart tool cache
├── .idea/            # IDE configuration (Android Studio)
├── .vscode/          # VS Code configuration
├── pubspec.yaml      # Project dependencies and metadata
├── pubspec.lock      # Locked dependency versions
├── README.md         # Project documentation
├── CHANGELOG.md      # Version history
├── analysis_options.yaml # Dart linter rules
└── .gitignore        # Git ignore rules

What's happening here? - Platform folders contain native code for each platform - lib/ is where all Dart code lives - pubspec.yaml is the most important configuration file - build/ is generated and should be ignored in git - Platform folders are auto-generated by Flutter


lib Folder

The lib/ folder is where all your Dart source code goes.

lib/
├── main.dart              # Entry point of the application
├── models/                # Data models
│   ├── user.dart
│   └── product.dart
├── screens/               # Full screen widgets
│   ├── home_screen.dart
│   ├── login_screen.dart
│   └── profile_screen.dart
├── widgets/               # Reusable widgets
│   ├── custom_button.dart
│   └── loading_indicator.dart
├── services/              # Business logic and API calls
│   ├── api_service.dart
│   └── auth_service.dart
├── utils/                 # Helper functions and constants
│   ├── constants.dart
│   └── validators.dart
├── providers/             # State management
│   ├── auth_provider.dart
│   └── theme_provider.dart
└── config/                # App configuration
    ├── routes.dart
    └── themes.dart

What's happening here? - main.dart is the entry point with main() function - Organize by feature or type (models, screens, widgets) - Keep business logic separate from UI - Use clear naming conventions - Folder structure can be customized


pubspec.yaml

The pubspec.yaml file defines your project's metadata, dependencies, and assets.

name: my_flutter_app
description: A new Flutter project.
version: 1.0.0+1

environment:
  sdk: '>=3.0.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter

  # UI and styling
  cupertino_icons: ^1.0.6
  google_fonts: ^5.0.0

  # State management
  provider: ^6.0.0

  # Networking
  http: ^1.1.0

  # Local storage
  shared_preferences: ^2.2.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0

flutter:
  uses-material-design: true

  # Assets
  assets:
    - assets/images/
    - assets/fonts/
    - assets/config.json

  # Fonts
  fonts:
    - family: CustomFont
      fonts:
        - asset: assets/fonts/CustomFont-Regular.ttf
        - asset: assets/fonts/CustomFont-Bold.ttf
          weight: 700

What's happening here? - name and version identify your package - dependencies are packages your app needs - dev_dependencies are only needed during development - flutter: section configures assets and fonts - Version constraints use semantic versioning


Android Folder

The android/ folder contains Android-specific configuration and code.

android/
├── app/
│   ├── src/
│   │   ├── main/
│   │   │   ├── java/          # Java/Kotlin code
│   │   │   ├── kotlin/        # Kotlin code (modern)
│   │   │   ├── res/           # Resources (images, layouts)
│   │   │   └── AndroidManifest.xml  # App manifest
│   │   ├── debug/
│   │   └── profile/
│   ├── build.gradle           # App-level build config
│   └── proguard-rules.pro     # Code obfuscation
├── gradle/
│   └── wrapper/
│       └── gradle-wrapper.properties
├── build.gradle              # Project-level build config
├── settings.gradle           # Project settings
├── gradle.properties         # Gradle properties
├── gradlew                   # Gradle wrapper (Unix)
├── gradlew.bat               # Gradle wrapper (Windows)
└── local.properties          # Local machine settings (ignored)

What's happening here? - Contains Android-specific build configuration - AndroidManifest.xml defines app permissions and activities - res/ contains Android-specific resources - build.gradle files control the build process - local.properties stores local SDK path


iOS Folder

The ios/ folder contains iOS-specific configuration and code.

ios/
├── Runner/
│   ├── AppDelegate.swift      # App delegate
│   ├── GeneratedPluginRegistrant.m # Plugin registration
│   ├── GoogleService-Info.plist # Firebase config
│   ├── Info.plist            # App info and permissions
│   ├── Assets.xcassets/      # App icons and assets
│   └── Base.lproj/
│       ├── LaunchScreen.storyboard
│       └── Main.storyboard
├── Flutter/
│   ├── Generated.xcconfig    # Generated build config
│   └── Debug.xcconfig        # Debug build config
├── Podfile                   # CocoaPods dependencies
├── Podfile.lock              # Locked pods
├── Runner.xcworkspace        # Xcode workspace
├── Runner.xcodeproj          # Xcode project
└── Pods/                     # Installed pods (ignored)

What's happening here? - Contains iOS-specific build configuration - Runner/ contains the iOS app target - Info.plist defines app permissions - Podfile manages CocoaPods dependencies - Opens with .xcworkspace in Xcode


Web Folder

The web/ folder contains web-specific configuration.

web/
├── index.html              # Main HTML entry
├── manifest.json           # PWA manifest
├── favicon.png            # App icon
├── icons/                 # App icons
│   ├── Icon-192.png
│   └── Icon-512.png
└── assets/
    └── fonts/             # Web fonts

What's happening here? - index.html is the web entry point - manifest.json enables progressive web app features - Icons support different display sizes - Can be customized for specific web needs


Test Folder

The test/ folder contains unit and widget tests.

test/
├── unit/                  # Unit tests
│   ├── models_test.dart
│   └── services_test.dart
├── widget/                # Widget tests
│   ├── home_screen_test.dart
│   └── custom_button_test.dart
├── integration/           # Integration tests
│   ├── app_test.dart
│   └── navigation_test.dart
└── test_helper.dart       # Test utilities

What's happening here? - Unit tests test individual functions and classes - Widget tests test UI components - Integration tests test full app flows - Tests should mirror your lib folder structure


Build Folder

The build/ folder contains generated output and should not be modified manually.

build/
├── app/                   # App-specific build output
├── ios/                   # iOS build output
├── android/               # Android build output
├── web/                   # Web build output
├── windows/               # Windows build output
├── macos/                 # macOS build output
└── linux/                 # Linux build output

What's happening here? - Contains compiled app files - Generated by Flutter build system - Should be ignored in .gitignore - Can be deleted and regenerated - Clean with flutter clean


Common Customizations

Feature-Based Organization

lib/
├── features/
│   ├── auth/
│   │   ├── models/
│   │   ├── screens/
│   │   ├── widgets/
│   │   └── services/
│   ├── home/
│   │   ├── models/
│   │   ├── screens/
│   │   └── widgets/
│   └── profile/
│       ├── models/
│       ├── screens/
│       └── widgets/
├── core/
│   ├── utils/
│   ├── constants/
│   └── themes/
└── main.dart

Clean Architecture

lib/
├── data/
│   ├── datasources/
│   ├── models/
│   └── repositories/
├── domain/
│   ├── entities/
│   ├── usecases/
│   └── repositories/
├── presentation/
│   ├── blocs/
│   ├── screens/
│   └── widgets/
└── main.dart

Best Practices

  • Keep main.dart minimal - use it only for app setup
  • Organize code by features, not by type
  • Use clear and consistent naming conventions
  • Keep platform-specific code in respective folders
  • Use pubspec.yaml to manage dependencies
  • Keep lib/ organized and clean
  • Use analysis_options.yaml for lint rules

Common Mistakes

Putting Everything in main.dart

Wrong:

// All code in one file
void main() { ... }
class HomeScreen { ... }
class UserModel { ... }
class ApiService { ... }

Correct:

lib/
├── main.dart
├── screens/
├── models/
└── services/


Ignoring pubspec.lock

Wrong:

# Not committing pubspec.lock

Correct:

# Commit pubspec.lock to ensure consistent builds
# It locks dependency versions across team members


Placing Assets Wrong

Wrong:

lib/assets/images/logo.png  # Assets in lib folder

Correct:

assets/images/logo.png      # Assets outside lib


Summary

A Flutter project has a well-defined structure with lib/ for Dart code, platform-specific folders for native code, and configuration files like pubspec.yaml. Understanding this structure helps you organize code effectively and navigate projects with ease.


Next Steps


Did You Know?

  • You can create projects with flutter create -t for templates
  • Flutter generates platform folders automatically
  • You can use flutter clean to delete build directory
  • pubspec.yaml supports path dependencies for local packages
  • The build/ folder can be 100MB+ for large projects
  • Flutter supports custom project templates