Your First Flutter App
Published April 2026
Introduction
Embarking on the journey of cross-platform mobile development can feel daunting with complex configurations and boilerplate setups. Fortunately, Flutter provides one of the most streamlined onboarding experiences in the modern software engineering space. By leveraging Google's Software Development Kit (SDK), developers can create applications that run flawlessly across mobile, web, and desktop environments from a single codebase.
In this guide, you will learn how to initialize your very first Flutter project from scratch using the Command Line Interface (CLI). We will demystify the automatically generated folders, dissect the entry point of a Flutter application, and build a compiler-valid, interactive welcome screen. This hands-on process helps you understand how Flutter translates code configurations into high-performance visual interfaces.
By the end of this tutorial, you will have a fully functioning application running on your emulator or physical device. You will also understand the exact flow of data from the Dart compiler down to the rendering window, establishing a solid foundation for the remainder of your learning path.
Prerequisites
Before building your application, ensure that you have configured your environment:
- Installed the Flutter SDK and added the tools to your terminal PATH.
- Set up a code editor (we highly recommend VS Code with Flutter and Dart extensions installed).
- Configured an emulator (Android Emulator or iOS Simulator) or enabled developer mode on a physical device connected to your machine.
- Verify your installation by running
flutter doctorin your terminal. All primary checkmarks should show as green.
Core Explanation: The Flutter CLI & Directory Structure
To start building, we must generate the project template using the Flutter CLI. The terminal commands are straightforward and prepare a boilerplate layout with support for Android, iOS, Web, and Desktop environments.
Project Initialization
Open your terminal, navigate to your desired workspace, and execute the following command:
flutter create my_first_app
This creates a new folder named my_first_app containing the standard structure. Open this directory in your editor:
cd my_first_app
Understanding the Directory Tree
The generated folder contains several files. Here are the core files you must understand:
lib/: This is the heart of your application. Almost all of your Dart code, widgets, and logic will be written in this directory. By default, it contains the main entry point:lib/main.dart.pubspec.yaml: The project configuration file. This is where you declare app metadata, manage dependency packages (like HTTP tools or database interfaces), and define local assets (images, custom fonts).android/,ios/,web/,linux/,macos/,windows/: These folders contain the platform-specific wrapper projects. When you compile your app, the Flutter build tool uses these templates to embed the Dart compiler engine and generate target bundles.
The Entry Point
Every Flutter app starts at the main() function, located in lib/main.dart. This function executes first, calling runApp(). The runApp() method binds the root widget to the device screen, launching the framework engine.
Practical Example: Building a Welcome App
Let's write a complete, compiler-ready welcome application. Replace the entire content of your lib/main.dart file with the following clean code block:
import 'package:flutter/material.dart';
void main() {
// The entry point of the app, running our root widget.
runApp(const MyApp());
}
/// The root widget of the application.
/// It configures global theme styles and launches the Home screen.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My First App',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const WelcomePage(),
);
}
}
/// The home screen widget representing our interactive page.
class WelcomePage extends StatefulWidget {
const WelcomePage({super.key});
@override
State<WelcomePage> createState() => _WelcomePageState();
}
class _WelcomePageState extends State<WelcomePage> {
// Interactive state parameter tracking the greeting status
bool _isLiked = false;
void _toggleLike() {
setState(() {
_isLiked = !_isLiked;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Welcome to Flutter'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
centerTitle: true,
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Hello World!',
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 16.0),
Text(
'You have successfully built and run your first Flutter application. This interactive greeting responds to state modifications.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
color: Colors.grey[700],
),
),
const SizedBox(height: 24.0),
// Conditional text display based on state
Text(
_isLiked ? 'Thank you for liking!' : 'Do you like this guide?',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: _isLiked ? Colors.deepPurple : Colors.grey[800],
),
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _toggleLike,
tooltip: 'Toggle Like',
child: Icon(
_isLiked ? Icons.favorite : Icons.favorite_border,
color: Colors.red,
),
),
);
}
}
Code Explanation:
package:flutter/material.dart: Imports Flutter's standard Material Design widgets.MaterialApp: The root configuration component that sets up themes, titles, and routing.Scaffold: Implements the basic Material visual layout structure (app bar, body padding, and floating action button placeholders).StatefulWidget&setState: Allows us to keep track of variables (like_isLiked) and callsetStateto tell Flutter to redraw the screen when they change.
Visual Breakdown
Let's examine how the widget trees translate during runtime initialization:
MyApp (Root Configurations)
└── MaterialApp (Material contexts, fonts, styles)
└── WelcomePage (Stateful Component Container)
└── Scaffold (Basic layout scaffolding structure)
├── AppBar (Header bar with titles)
├── Center (Centering viewport container)
│ └── Padding (Inner padding bounds)
│ └── Column (Vertical linear layout)
│ ├── Text ("Hello World!")
│ ├── SizedBox (Spacing spacer)
│ ├── Text (Body description)
│ ├── SizedBox (Spacing spacer)
│ └── Text (Conditional status string)
└── FloatingActionButton (Interactive trigger button)
- Execution Flow: When the
FloatingActionButtonis tapped,_toggleLikeis called. The internalsetStateupdates the boolean value of_isLiked, triggering a repaint ofWelcomePageand updating the text on the screen.
Common Mistakes
1. SDK Version Conflict
Running commands and getting "The current Dart SDK version is..." errors is very common.
- The Fix: Ensure your
pubspec.yamltarget SDK version matches your installed version. Runningflutter upgradeupdates your local toolsets.
2. Missing MaterialApp Root
Trying to run widgets without wrapping them in a MaterialApp or CupertinoApp root container will cause text rendering issues (such as double yellow underline decorations).
- The Fix: Always declare a
MaterialApporCupertinoAppat the very top of your widget structure to provide text direction and theme contexts.
3. Modifying Platform Directories Directly
New developers often attempt to build native screens in /android or /ios files directly instead of composing layouts inside the /lib folder.
- The Fix: Keep all UI layout setups in
/liband rely on Flutter's compiler to generate native views. Only open platform directories for native configuration details (like app icons or key sign certificates).
Best Practices
- Run
flutter doctorProactively: Whenever you hit compilation crashes, runflutter doctorto detect configuration issues in your toolsets. - Leverage Auto-Formatting: Use Dart's built-in formatting tools (
dart format .or VS Code shortcut) to ensure your code formatting remains clean and readable. - Keep Platform Folders Intact: Do not delete platform folders unless you explicitly plan to re-generate them using
flutter create ..
Related Concepts
Continue your Flutter learning journey by exploring these related topics:
- Understanding Widgets in Flutter: Learn the differences between design configurations and structural element trees.
- Stateless vs. Stateful Widgets: Dive deep into state lifecycles and when to use stateless vs. stateful widgets.
- Row vs. Column Layout Guide: Master layout principles and alignment configurations along cross and main axes.
Summary
- Use
flutter createto initialize a new project layout from the terminal. - Your Dart code lives in
/lib, and dependency configurations are managed inpubspec.yaml. - The
main()function is the application entry point, executingrunApp()to start the framework engine. - Flutter updates the screen dynamically by rebuilding layout configurations whenever state modifications trigger
setState.
Next Steps
- Next Guide: Understanding Widgets in Flutter
- Related Guide: Stateless vs. Stateful Widgets
- Related Guide: Row vs. Column Layout Guide
Ready to take the next step?
Start our free Flutter course and build real apps today.
Start Learning Now