Files in your Flutter Project

 In a Flutter project, the files are organized so that your Dart application code, UI resources, platform-specific Android/iOS code, dependencies, and build configuration remain separated.

A typical project looks like this:

my_flutter_app/
├── lib/
│   └── main.dart
├── test/
├── android/
├── ios/
├── web/
├── windows/
├── macos/
├── linux/
├── pubspec.yaml
├── pubspec.lock
├── analysis_options.yaml
├── .gitignore
└── README.md

1. lib/ ⭐ Most important

This is where almost all of your Flutter application code lives.

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

For most day-to-day Flutter development, you spend the majority of your time here.

main.dart

The entry point of the Flutter application.

A minimal example:

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text('Hello Flutter'),
        ),
      ),
    );
  }
}

Execution starts with:

main()

which normally calls:

runApp()

to start the Flutter widget tree.


2. pubspec.yaml ⭐ Very important

Think of this as the configuration/manifest file of your Flutter project.

It defines things such as:

  • Project name
  • Version
  • Dart/SDK constraints
  • Flutter dependencies
  • Third-party packages
  • Fonts
  • Images and other assets

Example:

name: my_app
environment:
  sdk: ^3.0.0
dependencies:
  flutter:
    sdk: flutter
  http: ^1.0.0
  provider: ^6.0.0
flutter:
  assets:
    - assets/images/

If you want to use a package such as:

import 'package:http/http.dart';

you would normally declare http under dependencies.

After changing dependencies, you typically run:

flutter pub get


3. pubspec.lock

Records the exact versions of packages resolved for your project.

For example, pubspec.yaml might allow a compatible range, while pubspec.lock records the particular version selected.

Conceptually:

pubspec.yaml
     ↓
"These package versions are allowed"
     ↓
Flutter/Dart resolves dependencies
     ↓
pubspec.lock
     ↓
"These exact versions were selected"

For Flutter applications, this file is normally committed to Git so developers and CI use consistent resolved versions.


4. android/

Contains the native Android project used to package and run your Flutter application on Android.

Typical contents include:

android/
├── app/
├── gradle/
├── build.gradle.kts
├── settings.gradle.kts
└── gradle.properties

You usually modify this directory when dealing with things like:

  • Android permissions
  • Native Android integrations
  • Gradle configuration
  • App signing
  • Android-specific SDK configuration
  • Package/application settings

For example, Android permissions are configured through:

android/app/src/main/AndroidManifest.xml

You might add internet or other native permissions there.


5. ios/

The equivalent native project for iPhone/iPad.

ios/
├── Runner/
├── Runner.xcodeproj/
├── Runner.xcworkspace/
└── Podfile

Used when configuring things such as:

  • iOS permissions
  • Apple signing
  • Bundle identifiers
  • CocoaPods
  • Native Swift/Objective-C integration
  • iOS-specific settings

For example:

ios/Runner/Info.plist

contains many iOS application configuration values.


6. web/

Contains Flutter Web-specific files.

Common files include:

web/
├── index.html
├── manifest.json
└── icons/

index.html

Acts as the HTML host/bootstrap page for the Flutter web application.

manifest.json

Contains metadata relevant to the web app/PWA experience, such as name, icons, and display behavior.


7. windows/

Native Windows desktop application wrapper/configuration.

Usually contains C++ and build configuration associated with running your Flutter UI as a Windows application.

You generally touch this folder only when you need Windows-specific functionality or configuration.


8. macos/

Native macOS application project.

Similar to ios/, it contains Apple-specific runner and Xcode configuration for building your Flutter application for macOS.


9. linux/

Contains the native Linux runner and build configuration.

You'll primarily interact with it when implementing Linux-specific functionality or customizing the application's native Linux integration.


10. test/

Contains automated Dart/Flutter tests.

For example:

test/
└── widget_test.dart

A simple widget test may look like:

testWidgets('Login button is displayed', (tester) async {
  await tester.pumpWidget(const MyApp());
  expect(find.text('Login'), findsOneWidget);
});

As your application grows, you might organize it as:

test/
├── unit/
├── widgets/
└── services/


11. analysis_options.yaml

Configures the Dart analyzer and linting rules.

For example, it can help enforce coding standards and flag issues while you develop.

Think of it as:

"Rules for checking the quality and consistency of my Dart code."


12. .gitignore

Tells Git which generated/local files should not be committed.

Typical examples include build artifacts and IDE-specific files.


13. .dart_tool/

An automatically generated directory used internally by Dart and Flutter tooling.

It can contain:

  • Package configuration
  • Build information
  • Tool metadata

Normally:

Don't manually modify this folder.


14. build/

Contains generated build output.

Flutter creates it when compiling/building the application.

For example:

flutter build apk

or

flutter build web

will generate build artifacts.

You normally do not manually edit anything inside build/.


A real application's lib folder

The default Flutter project is intentionally simple. For your own application, the structure might evolve into something like:

lib/
├── main.dart
│
├── models/
│   ├── user.dart
│   └── product.dart
│
├── screens/
│   ├── login_screen.dart
│   ├── home_screen.dart
│   └── product_screen.dart
│
├── widgets/
│   ├── product_card.dart
│   └── custom_button.dart
│
├── services/
│   ├── api_service.dart
│   └── auth_service.dart
│
├── providers/
│   └── auth_provider.dart
│
└── utils/
    ├── constants.dart
    └── validators.dart

The responsibilities could be:

FolderPurpose
models/Data/domain objects such as User, SalesOrder, Customer
screens/Complete application pages
widgets/Reusable UI components
services/APIs, databases, authentication, etc.
providers/Application/state-management logic when using Provider
utils/Common utilities, constants, validators

For example, if you were building an ERP-style Flutter application, you could structure a Sales Order feature as:

lib/
├── main.dart
├── models/
│   ├── customer.dart
│   └── sales_order.dart
├── screens/
│   ├── sales_order_list.dart
│   └── sales_order_detail.dart
├── widgets/
│   └── sales_order_card.dart
└── services/
    └── sales_order_api.dart

The basic flow becomes:

main.dart → Screen → Widget → Service/API → Model → UI

That separation becomes increasingly important as your Flutter application grows.

Comments

Popular posts from this blog

Flutter setup on Windows 11 using VS Code + Android Emulator

Understanding single-page flutter app with state