iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Project Structure

Anatomy of a Flutter project: pubspec.yaml, lib/, assets, platforms, run + build + flavours. The structure underneath flutter create.

Flutter — project anatomy

EXAMPLE
# ===== After 'flutter create my_app' =====
# my_app/
#   pubspec.yaml          dependencies + assets + metadata
#   lib/
#     main.dart           entry: runApp(MyApp())
#   test/
#     widget_test.dart    sample widget test
#   android/              Android Studio project
#   ios/                  Xcode project
#   web/                  index.html + manifests
#   macos/ windows/ linux/  desktop hosts
#   .dart_tool/           cache (gitignored)
#   build/                build outputs (gitignored)

# ===== pubspec.yaml =====
name: my_app
description: A new Flutter project.
version: 1.0.0+1            # <semver>+<build_number>

environment:
  sdk: '>=3.4.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.0
  provider: ^6.1.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^4.0.0

flutter:
  uses-material-design: true
  assets:
    - assets/images/
  fonts:
    - family: Inter
      fonts:
        - asset: assets/fonts/Inter-Regular.ttf
        - asset: assets/fonts/Inter-Bold.ttf
          weight: 700

# After editing:
flutter pub get

# ===== lib/ layout (small project) =====
# lib/
#   main.dart
#   app.dart           MaterialApp + theme + router
#   theme.dart
#   features/
#     orders/
#       order.dart           model
#       orders_provider.dart state
#       orders_page.dart     UI
#   shared/
#     widgets/
#     utils/

# ===== A run-friendly main.dart =====
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) => MaterialApp(
    title: 'My App',
    theme: ThemeData(useMaterial3: true),
    home: const HomePage(),
  );
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});
  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(title: const Text('Home')),
    body: const Center(child: Text('Hello, Flutter')),
  );
}

# ===== Run + build =====
flutter run                              # to current device
flutter run -d chrome                    # web
flutter run -d macos                     # desktop
flutter run --release                    # release build, even in dev
flutter build apk --release              # Android APK
flutter build appbundle --release        # AAB for Play Store
flutter build ipa --release              # iOS IPA (macOS only)
flutter build web --release              # static web bundle

# ===== Flavours / environments =====
# Define in android/app/build.gradle + ios/Runner.xcodeproj:
#   prod, staging, dev
# Then:
flutter run --flavor staging -t lib/main_staging.dart

# Or simpler: --dart-define
flutter run --dart-define=API=https://staging.example.com

const apiUrl = String.fromEnvironment('API', defaultValue: 'http://localhost:3000');

# ===== Useful CLI =====
flutter clean             # nuke build/ + .dart_tool/
flutter pub get / upgrade
flutter pub outdated
flutter analyze           # lint + type check
dart format .             # format

# ===== Patterns to internalise =====
# - One state-management library per app (Provider, Riverpod, Bloc)
# - --dart-define for environment config; do not hardcode
# - flutter analyze in CI as a required check
# - lib/features/<area>/ over a 'screens' grab-bag

# ===== Pitfalls =====
# - Mismatched Flutter + Dart SDK constraints in pubspec
# - Mixing UI + business logic in one widget tree
# - Forgetting to include assets/fonts in pubspec after adding files
# - Building release APK without signing config -> can't ship

Why it matters

A Flutter project is pubspec.yaml + lib/ + per-platform host directories. Pin SDK constraints, declare assets + fonts in pubspec, organise lib by feature, and lean on --dart-define for environments. The same project ships to six platforms with the same conventions; the discipline is keeping the lib tree tidy.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// myapp/
//     lib/                main.dart, widgets/, screens/
//     test/               unit + widget tests
//     android/  ios/  web/
//     pubspec.yaml        deps, assets, version
Try it Yourself »

Discussion

Loading…