In plain words
Before you can build Flutter apps, your computer needs a small workshop: the Flutter SDK (the tools and the framework, with Dart included), an editor to write code, and somewhere to run the app, such as an Android emulator, your own phone, Chrome or your desktop.
Setting up is like preparing a kitchen before cooking. It takes an hour or two the first time, and then you rarely think about it again. Flutter even includes an inspector for your kitchen: flutter doctor checks every tool and tells you what is missing.
If you want to start right now, DartPad (dartpad.dev) runs Dart and Flutter code in the browser. Most small examples in this course work there. It cannot run plugins such as Firebase or sqflite, so for those lessons you need the full setup.
Why it matters
A broken setup wastes more beginner hours than any language feature. Common problems are a missing Android licence, an emulator that will not start, or two different Flutter versions on the same machine. A clean, checked setup means that when something fails, it is your code and not your tools.
In a job, you will also set up machines for new projects, CI servers and teammates. Knowing what each piece does (SDK, toolchain, device, editor) makes you the person who can fix “it works on my machine” problems.
How it works
The setup has five parts. Install them in this order, and run flutter doctor after each one.
1. Install the Flutter SDK
Follow the install guide for your operating system on docs.flutter.dev. You can either let the VS Code Flutter extension download the SDK for you, or download it yourself and add its bin folder to your PATH. The SDK contains the flutter command, the framework source, the engine and a matching Dart SDK, so you do not install Dart separately.
Check it works in a new terminal:
flutter --version flutter doctor
Stay on the stable channel for course work and client projects. Update later with flutter upgrade.
2. Choose an editor
| Editor | Add | Good for |
|---|---|---|
| VS Code | The Flutter extension (it installs the Dart extension too) | Light and fast; the most common choice |
| Android Studio | The Flutter plugin (it adds the Dart plugin) | Includes the Android SDK and emulator manager in one place |
Both give you code completion, quick fixes, a debugger, hot reload on save and access to Flutter DevTools.
3. Set up a target platform
- Android: install Android Studio (even if you code in VS Code) to get the Android SDK, command-line tools and an emulator. Then accept the licences with
flutter doctor --android-licenses. Create a virtual device in the Device Manager, or connect a real phone with USB debugging turned on in Developer options. - iOS and macOS: need a Mac with Xcode. Open the iOS Simulator from Xcode, or connect an iPhone.
- Web: Chrome is enough.
- Desktop: each desktop platform builds on its own OS. Windows desktop apps need Visual Studio (not VS Code) with the “Desktop development with C++” workload.
List what Flutter can see:
flutter devices flutter emulators flutter emulators --launch <emulator_id>
4. Create and run a project
flutter create hello_flutter cd hello_flutter flutter run
Use lowercase with underscores for project names. In real projects add your organisation’s reverse domain, which becomes the Android package and iOS bundle ID: flutter create --org com.ralfiz hello_flutter. Changing it later is tedious, so choose it at the start.
While flutter run is active in a terminal, press r for hot reload, R for hot restart and q to quit. In VS Code, saving a file triggers hot reload.
| Hot reload | Hot restart | Full restart | |
|---|---|---|---|
| Keeps app state | Yes | No | No |
| Speed | About a second | A few seconds | Full build |
| Use after | Changing build methods and most code | Changing main(), global or static initialisers, or when the screen looks stale | Adding a plugin, changing native files or pubspec assets |
5. Know the project structure
| Path | What it holds |
|---|---|
lib/main.dart | Your Dart code starts here. Nearly all your work lives in lib/. |
pubspec.yaml | App name, version, Dart SDK constraint, dependencies, assets and fonts. |
pubspec.lock | The exact package versions resolved. Commit it for apps. |
test/ | Tests; the template includes widget_test.dart. |
analysis_options.yaml | Lint rules, starting with the recommended flutter_lints set. |
android/, ios/, web/, windows/, macos/, linux/ | Platform host projects: icons, permissions, signing, native settings. |
build/, .dart_tool/ | Generated files. Never edit or commit them. |
Packages are added with flutter pub add, which updates pubspec.yaml and downloads the package:
flutter pub add http flutter pub get
Example: your first run of the counter app
Every new project starts with the counter app. It is worth reading slowly, because it already contains the core of Flutter: a stateless root widget, a stateful page, setState and a theme built from a seed colour.
- Run
flutter create --org com.example hello_flutter, open the folder in your editor, and choose a device in the status bar (VS Code) or the device menu (Android Studio). - Start the app with
flutter runor the Run button. The first Android build takes a few minutes while Gradle downloads its tools; later builds are much faster. - Tap the + button three times. The number goes from 0 to 3.
- Change the text
'You have pushed the button this many times:'to'Taps so far:'and save. Hot reload shows the new text and the counter still says 3. - Now press R for hot restart. The counter goes back to 0, because the whole app, and its state, was restarted.
Screen 1: The starter counter app lib/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) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
A trimmed copy of what flutter create generates. Each tap on + calls setState, which rebuilds the widget and shows the new count. The app bar uses the colour scheme’s inversePrimary role. States: First run → After 3 taps.
This is a trimmed copy of the generated code (the template also has comments explaining each part). You will write your own version in the lab.
Common mistakes
- Ignoring flutter doctor. Read every line with a cross or an exclamation mark. It usually names the fix, for example running
flutter doctor --android-licenses. - Installing the SDK in a protected folder such as
C:\Program Files, or a path with spaces or special characters. Use something likeC:\dev\flutteror~/development/flutter. - Two Flutter SDKs on one machine. Your terminal and your editor may use different ones. Check with
which flutter(macOS/Linux) orwhere flutter(Windows), and point the editor at the same SDK. - Expecting hot reload to pick up everything. Changes to
main(), static fields, native code, plugins and assets need a hot restart or a full rebuild. - Editing files in build/ or committing them. They are regenerated on every build. Keep them out of version control.
- Using CamelCase or hyphens in project names. Dart package names must be lowercase with underscores.
Interview and real-world notes
- You may be asked “What is the difference between hot reload and hot restart?” Answer with state: reload keeps it, restart resets it, and explain when reload is not enough.
- On a team, everyone should use the same Flutter version. Many teams record it in the README or use a version manager such as FVM, and CI pins the same version.
- Start every project with the
--orgyou will publish under. The package name appears in the Play Store URL and cannot change after publishing. - Keep
flutter analyzeclean from day one. Reviewers notice warnings.