Courses

Dart Programming for Beginners: The Basics You Need Before Flutter

The Dart you actually need before Flutter: variables, null safety, collections, functions, classes and async, each with a short example and where it appears in an app.

By Nazmul Hussain Published Updated 8 min read

Code editor showing short Dart examples beside a phone running a simple Flutter screen

Flutter is written in Dart, and every widget, button and screen you build is Dart code. Many beginners skip straight to widgets and end up confused by errors that have nothing to do with Flutter. This guide to Dart programming for beginners covers the basics you need first: variables, null safety, collections, functions, classes and async code, each with a short example and a note on where it appears in a real Flutter app.

It follows the Month 1 foundations of Omebly Academy’s live Flutter App Development course, where Dart basics come before widgets and layouts.

Quick answer: Before Flutter, learn Dart’s variables and types (var, final, const), null safety, strings, lists and maps, control flow, functions with named parameters, classes and constructors, and async code with Future, async and await. Practise in DartPad for two to three weeks, then move to Flutter widgets, where you will use every one of these daily.

What Dart is and why Flutter uses it

Dart is an open-source, typed programming language made by Google. Flutter uses it because it compiles to fast native code for release builds and supports hot reload while you develop, so you see changes in a second or two.

You can run every example here in DartPad, the official browser editor. The Dart language tour is the reference to keep open while you learn.

Every Dart program starts at main:

void main() {
  print('Hello, Omebly!');
}

1. Variables and types

var city = 'Kolkata';      // type inferred as String
int students = 24;
double rating = 4.5;
bool isLive = true;

final joinedAt = DateTime.now(); // set once, at runtime
const maxSeats = 10;             // fixed at compile time
  • var lets Dart infer the type. Once set, the type can’t change.
  • final means “assign once”. Use it for most values that shouldn’t change.
  • const means the value is known before the program runs.

In Flutter: you will write const Text('Hello') and const SizedBox(height: 16) constantly. Const widgets can be reused instead of rebuilt.

2. Null safety

Dart variables can’t be null unless you allow it with ?.

String name = 'Asha';     // can never be null
String? nickname;         // may be null

print(nickname ?? 'No nickname');   // fallback if null
print(nickname?.length);            // null-aware access
  • ?? gives a default when a value is null.
  • ?. calls something only if the value isn’t null.
  • ! tells Dart “I’m sure this isn’t null”. Use it rarely; if you are wrong, the app crashes.
  • late promises a value will be set before it’s used.

In Flutter: data from an API or a form is often missing. Null safety forces you to handle that case, which is why Flutter apps written well crash less.

3. Strings

var first = 'Ravi';
var greeting = 'Hi $first, you have ${2 + 3} new messages';
var multi = '''
Line one
Line two
''';

Use $name for a variable and ${...} for an expression. You will build almost every on-screen label this way.

4. Collections: List, Map and Set

List<String> courses = ['Flutter', 'Python', 'SQL'];
courses.add('Power BI');

Map<String, int> scores = {'Asha': 82, 'Ravi': 91};
print(scores['Ravi']); // 91

Set<String> tags = {'mobile', 'android', 'mobile'}; // keeps 2 items

The most useful collection methods:

var upper = courses.map((c) => c.toUpperCase()).toList();
var short = courses.where((c) => c.length <= 6).toList();
var hasSql = courses.contains('SQL');

Dart also has collection if and for, which you will meet in Flutter layouts:

var items = [
  'Home',
  if (isLive) 'Live now',
  for (var c in courses) 'Course: $c',
];

In Flutter: a Column’s children is a list, so collection if and for let you show or repeat widgets cleanly.

5. Control flow

if (students > 20) {
  print('Full class');
} else {
  print('Seats available');
}

for (var c in courses) {
  print(c);
}

var level = switch (rating) {
  >= 4.5 => 'Excellent',
  >= 3.5 => 'Good',
  _ => 'Needs work',
};

The switch expression above uses Dart 3 patterns. It is short, and the compiler checks that every case is covered.

6. Functions and named parameters

int add(int a, int b) => a + b;   // arrow syntax for one expression

void bookSeat({required String name, int seat = 1}) {
  print('$name booked seat $seat');
}

bookSeat(name: 'Asha', seat: 3);
  • Named parameters go in {} and are passed by name.
  • required makes a named parameter compulsory.
  • Default values fill in what the caller leaves out.
  • Functions are values, so you can pass them around.

In Flutter: almost every widget uses named parameters, such as Text('Hi', style: ...) or ElevatedButton(onPressed: () {...}, child: ...). That onPressed is a function passed as a value.

7. Classes, constructors and objects

class Course {
  final String title;
  final int months;

  const Course({required this.title, required this.months});

  Course.short(String title) : this(title: title, months: 3);

  String get label => '$title ($months months)';
}

var flutter = Course(title: 'Flutter', months: 6);
var sql = Course.short('SQL');
print(flutter.label);

What to understand here:

  • this.title in a constructor assigns the field directly.
  • Named constructors such as Course.short give alternative ways to create objects.
  • Getters compute a value that reads like a field.
  • extends lets one class build on another, and @override replaces a method.

In Flutter: every widget is a class. When you write class ProfileCard extends StatelessWidget, you are using exactly this.

Converting JSON to objects

factory Course.fromJson(Map<String, dynamic> json) {
  return Course(title: json['title'], months: json['months']);
}

A factory constructor like this sits inside the class and turns API data into typed objects. It is one of the first patterns you write in a real app.

8. Async code: Future, async and await

Network calls and database reads take time. Dart handles them with Future.

Future<String> loadUserName() async {
  await Future.delayed(const Duration(seconds: 1));
  return 'Asha';
}

void main() async {
  try {
    var name = await loadUserName();
    print('Welcome, $name');
  } catch (e) {
    print('Something went wrong: $e');
  }
}
  • A Future is a value that arrives later.
  • async marks a function that waits for futures.
  • await pauses until the value is ready, without freezing the app.
  • try and catch handle failures such as no internet.
  • A Stream delivers many values over time, such as live chat messages.

In Flutter: you will await API calls, Firebase reads and local storage, and use FutureBuilder or StreamBuilder to show loading, data and error states.

Dart programming for beginners: a quick glossary

Term Meaning Where you’ll see it in Flutter
final / const Can’t be reassigned const widgets, settings
? and ?? Nullable type and fallback API data, form fields
List / Map Ordered items / key-value pairs Widget children, JSON
Named parameters Arguments passed by name Almost every widget
Class Blueprint for objects Every widget and model
Future A value that arrives later API calls, storage
Stream Values over time Real-time chat, live data
Package Reusable library from pub.dev HTTP, state management

A two-week Dart practice plan

  1. Days 1–3: variables, types, strings and null safety. Write a small tip calculator in DartPad.
  2. Days 4–6: lists, maps and loops. Build a marks report that prints grades for a class.
  3. Days 7–9: functions and classes. Model a Student and Course with constructors and getters.
  4. Days 10–12: JSON and async. Parse a JSON string into objects and simulate a delayed fetch.
  5. Days 13–14: a mini command-line app, such as a to-do list, combining everything.

Then move to Flutter widgets. Our Flutter learning roadmap picks up from here, and if you are still choosing a framework, read Flutter vs React Native for beginners.

Common Dart mistakes beginners make

  • Using ! everywhere to silence null errors. Handle the null case instead.
  • Using dynamic when you could give a proper type.
  • Forgetting await, then wondering why a value is a Future instead of data.
  • Making everything var instead of final. Default to final.
  • Skipping classes and passing maps around the whole app.

Ready-for-Flutter checklist

  • I know when to use var, final and const
  • I can handle nullable values without !
  • I can transform lists with map and where
  • I can write functions with named and required parameters
  • I can write a class with a constructor and a fromJson factory
  • I can use async, await and try/catch

Learn it with Omebly

Omebly Academy’s Flutter App Development course starts with Dart basics in Month 1, then moves to widgets, layouts, navigation and state. It is live and mentor-led, with recordings and weekly one-to-one reviews, and no prior experience is needed. You work with Flutter, Dart, Android Studio, VS Code, Firebase, Postman, Git and GitHub, and Figma for design handoff.

  • Core (3 months, $699): Dart, widgets, state, forms, REST APIs, local storage, Firebase, authentication, notifications and publishing builds, with two capstone projects.
  • Professional (6 months, $1,199): adds clean architecture, testing, real-time features with WebSockets, animations and payments, with four capstones, mock interviews and portfolio review.
  • Career (12 months, $1,999): adds a Node.js backend for apps, performance and monitoring, and a live client-style project with the Omebly team, plus placement assistance (no job guarantee).

Have an app idea and would rather hire a team? See our Flutter app development service.

Questions about where to start? Message us on WhatsApp or contact us for a free first call.

Frequently asked questions

Do I need to learn Dart before Flutter?

You need the basics: variables, types, null safety, collections, functions, classes and async. You don't need to master the whole language first. Two to three weeks of steady Dart practice is enough to start building Flutter screens.

Is Dart easy for complete beginners?

Yes, as programming languages go. Its syntax is clean and readable, and its type system catches many mistakes before the app runs. If you have seen Java, C#, JavaScript or Kotlin, it will feel familiar.

Where can I practise Dart without installing anything?

DartPad, the official online editor at dartpad.dev, runs Dart in your browser. It is ideal for the exercises in this guide.

What is null safety in Dart?

Null safety means a variable can't hold null unless you say so with a question mark, such as String?. The compiler then forces you to handle the missing case, which prevents a whole class of crashes.

What is the difference between final and const in Dart?

Both stop a variable being reassigned. A final value is set once, possibly at runtime. A const value must be known at compile time. In Flutter, const widgets can also be reused, which helps performance.

Is Dart used outside Flutter?

Yes, for command-line tools and servers, but most people learn it for Flutter. That is the right reason to learn it, and the skills transfer to other typed languages.

Written by

Nazmul Hussain, Managing Director & Technical Head, Omebly. 10+ years building websites and apps for clients in India, the Gulf, the UK and the US, and mentoring at Omebly Academy. LinkedIn · GitHub