Dart 3.10 is taking off with dot shorthands, stable build hooks, nuanced deprecation annotations, and more!Learn more
Introduction to Dart
This page provides a brief introduction to the Dart language through samples of its main features.
To learn more about the Dart language, visit the in-depth, individual topic pages listed underLanguage in the left side menu.
For coverage of Dart's core libraries, check out thecore library documentation. You can also check out theDart cheatsheet, for a more interactive introduction.
Hello World
# Every app requires the top-levelmain() function, where execution starts. Functions that don't explicitly return a value have thevoid return type. To display text on the console, you can use the top-levelprint() function:
voidmain(){print('Hello, World!');} Read more aboutthemain() function in Dart, including optional parameters for command-line arguments.
Variables
# Even intype-safe Dart code, you can declare most variables without explicitly specifying their type usingvar. Thanks to type inference, these variables' types are determined by their initial values:
varname='Voyager I';varyear=1977;varantennaDiameter=3.7;varflybyObjects=['Jupiter','Saturn','Uranus','Neptune'];varimage={'tags':['saturn'],'url':'//path/to/saturn.jpg',};Read more about variables in Dart, including default values, thefinal andconst keywords, and static types.
Control flow statements
#Dart supports the usual control flow statements:
if(year>=2001){print('21st century');}elseif(year>=1901){print('20th century');}for(finalobjectinflybyObjects){print(object);}for(intmonth=1;month<=12;month++){print(month);}while(year<2016){year+=1;} Read more about control flow statements in Dart, includingbreak andcontinue,switch andcase, andassert.
Functions
#We recommend specifying the types of each function's arguments and return value:
intfibonacci(intn){if(n==0||n==1)returnn;returnfibonacci(n-1)+fibonacci(n-2);}varresult=fibonacci(20); A shorthand=> (arrow) syntax is handy for functions that contain a single statement. This syntax is especially useful when passing anonymous functions as arguments:
flybyObjects.where((name)=>name.contains('turn')).forEach(print); Besides showing an anonymous function (the argument towhere()), this code shows that you can use a function as an argument: the top-levelprint() function is an argument toforEach().
Read more about functions in Dart, including optional parameters, default parameter values, and lexical scope.
Comments
#Dart comments usually start with//.
// This is a normal, one-line comment./// This is a documentation comment, used to document libraries,/// classes, and their members. Tools like IDEs and dartdoc treat/// doc comments specially./* Comments like these are also supported.*/Read more about comments in Dart, including how the documentation tooling works.
Imports
#To access APIs defined in other libraries, useimport.
// Importing core librariesimport'dart:math';// Importing libraries from external packagesimport'package:test/test.dart';// Importing filesimport'path/to/my_other_file.dart';Read more about libraries and visibility in Dart, including library prefixes,show andhide, and lazy loading through thedeferred keyword.
Classes
#Here's an example of a class with three properties, two constructors, and a method. One of the properties can't be set directly, so it's defined using a getter method (instead of a variable). The method uses string interpolation to print variables' string equivalents inside of string literals.
classSpacecraft{Stringname;DateTime?launchDate;// Read-only non-final propertyint?getlaunchYear=>launchDate?.year;// Constructor, with syntactic sugar for assignment to members.Spacecraft(this.name,this.launchDate){// Initialization code goes here.}// Named constructor that forwards to the default one.Spacecraft.unlaunched(Stringname):this(name,null);// Method.voiddescribe(){print('Spacecraft:$name');// Type promotion doesn't work on getters.varlaunchDate=this.launchDate;if(launchDate!=null){intyears=DateTime.now().difference(launchDate).inDays~/365;print('Launched:$launchYear ($years years ago)');}else{print('Unlaunched');}}}Read more about strings, including string interpolation, literals, expressions, and thetoString() method.
You might use theSpacecraft class like this:
varvoyager=Spacecraft('Voyager I',DateTime(1977,9,5));voyager.describe();varvoyager3=Spacecraft.unlaunched('Voyager III');voyager3.describe();Read more about classes in Dart, including initializer lists, optionalnew andconst, redirecting constructors,factory constructors, getters, setters, and much more.
Enums
#Enums are a way of enumerating a predefined set of values or instances in a way which ensures that there cannot be any other instances of that type.
Here is an example of a simpleenum that defines a simple list of predefined planet types:
enumPlanetType{terrestrial,gas,ice}Here is an example of an enhanced enum declaration of a class describing planets, with a defined set of constant instances, namely the planets of our own solar system.
/// Enum that enumerates the different planets in our solar system/// and some of their properties.enumPlanet{mercury(planetType:PlanetType.terrestrial,moons:0,hasRings:false),venus(planetType:PlanetType.terrestrial,moons:0,hasRings:false),// ···uranus(planetType:PlanetType.ice,moons:27,hasRings:true),neptune(planetType:PlanetType.ice,moons:14,hasRings:true);/// A constant generating constructorconstPlanet({requiredthis.planetType,requiredthis.moons,requiredthis.hasRings,});/// All instance variables are finalfinalPlanetTypeplanetType;finalintmoons;finalboolhasRings;/// Enhanced enums support getters and other methodsboolgetisGiant=>planetType==PlanetType.gas||planetType==PlanetType.ice;}You might use thePlanet enum like this:
finalyourPlanet=Planet.earth;if(!yourPlanet.isGiant){print('Your planet is not a "giant planet".');} When the compiler can infer the enum type from the context, you can use the more concise dot-shorthand syntax to access enum values. Instead of writing the fullEnumName.value, you can just write.value. This can make your code cleaner and easier to read.
For example, when declaring a variable with an explicit type ofPlanet, you can omit the enum name because the type ofPlanet is already established:
// Instead of the full, explicit syntax:PlanetmyPlanet=Planet.venus;// You can use a dot shorthand:PlanetmyPlanet=.venus;Dot shorthands aren't limited to variable declarations. They can also be used in contexts like function arguments and switch cases where the enum type is clear to the compiler.
Read more about enums in Dart, including enhanced enum requirements, automatically introduced properties, accessing enumerated value names, switch statement support, and much more.Read more about dot shorthand syntax.
Inheritance
#Dart has single inheritance.
classOrbiterextendsSpacecraft{doublealtitude;Orbiter(super.name,DateTimesuper.launchDate,this.altitude);}Read more about extending classes, the optional@override annotation, and more.
Mixins
#Mixins are a way of reusing code in multiple class hierarchies. The following is a mixin declaration:
mixinPiloted{intastronauts=1;voiddescribeCrew(){print('Number of astronauts:$astronauts');}}To add a mixin's capabilities to a class, just extend the class with the mixin.
classPilotedCraftextendsSpacecraftwithPiloted{// ···}PilotedCraft now has theastronauts field as well as thedescribeCrew() method.
Read more about mixins.
Interfaces and abstract classes
#All classes implicitly define an interface. Therefore, you can implement any class.
classMockSpaceshipimplementsSpacecraft{// ···} Read more aboutimplicit interfaces, or about the explicitinterface keyword.
You can create an abstract class to be extended (or implemented) by a concrete class. Abstract classes can contain abstract methods (with empty bodies).
abstractclassDescribable{voiddescribe();voiddescribeWithEmphasis(){print('=========');describe();print('=========');}} Any class extendingDescribable has thedescribeWithEmphasis() method, which calls the extender's implementation ofdescribe().
Read more about abstract classes and methods.
Async
# Avoid callback hell and make your code much more readable by usingasync andawait.
constoneSecond=Duration(seconds:1);// ···Future<void>printWithDelay(Stringmessage)async{awaitFuture.delayed(oneSecond);print(message);}The method above is equivalent to:
Future<void>printWithDelay(Stringmessage){returnFuture.delayed(oneSecond).then((_){print(message);});} As the next example shows,async andawait help make asynchronous code easy to read.
Future<void>createDescriptions(Iterable<String>objects)async{for(finalobjectinobjects){try{varfile=File('$object.txt');if(awaitfile.exists()){varmodified=awaitfile.lastModified();print('File for$object already exists. It was modified on$modified.',);continue;}awaitfile.create();awaitfile.writeAsString('Start describing$object in this file.');}onIOExceptioncatch(e){print('Cannot create description for$object:$e');}}}You can also useasync*, which gives you a nice, readable way to build streams.
Stream<String>report(Spacecraftcraft,Iterable<String>objects)async*{for(finalobjectinobjects){awaitFuture.delayed(oneSecond);yield'${craft.name} flies by$object';}}Read more about asynchrony support, includingasync functions,Future,Stream, and the asynchronous loop (await for).
Exceptions
#To raise an exception, usethrow:
if(astronauts==0){throwStateError('No astronauts.');} To catch an exception, use atry statement withon orcatch (or both):
Future<void>describeFlybyObjects(List<String>flybyObjects)async{try{for(finalobjectinflybyObjects){vardescription=awaitFile('$object.txt').readAsString();print(description);}}onIOExceptioncatch(e){print('Could not describe object:$e');}finally{flybyObjects.clear();}} Note that the code above is asynchronous;try works for both synchronous and asynchronous code in anasync function.
Read more about exceptions, including stack traces,rethrow, and the difference betweenError andException.
Important concepts
#As you continue to learn about the Dart language, keep these facts and concepts in mind:
Everything you can place in a variable is anobject, and every object is an instance of aclass. Even numbers, functions, and
nullare objects. With the exception ofnull(if you enablesound null safety), all objects inherit from theObjectclass.Version noteNull safety was introduced in Dart 2.12. Using null safety requires alanguage version of at least 2.12.
Although Dart is strongly typed, type annotations are optional because Dart can infer types. In
var number = 101,numberis inferred to be of typeint.If you enablenull safety, variables can't contain
nullunless you say they can. You can make a variable nullable by putting a question mark (?) at the end of its type. For example, a variable of typeint?might be an integer, or it might benull. If youknow that an expression never evaluates tonullbut Dart disagrees, you can add!to assert that it isn't null (and to throw an exception if it is). An example:int x = nullableButNotNullInt!When you want to explicitly say that any type is allowed, use the type
Object?(if you've enabled null safety),Object, or—if you must defer type checking until runtime—thespecial typedynamic.Dart supports generic types, like
List<int>(a list of integers) orList<Object>(a list of objects of any type).Dart supports top-level functions (such as
main()), as well as functions tied to a class or object (static andinstance methods, respectively). You can also create functions within functions (nested orlocal functions).Similarly, Dart supports top-levelvariables, as well as variables tied to a class or object (static and instance variables). Instance variables are sometimes known asfields orproperties.
Unlike Java, Dart doesn't have the keywords
public,protected, andprivate. If an identifier starts with an underscore (_), it's private to its library. For details, seeLibraries and imports.Identifiers can start with a letter or underscore (
_), followed by any combination of those characters plus digits.Dart has bothexpressions (which have runtime values) andstatements (which don't). For example, theconditional expression
condition ? expr1 : expr2has a value ofexpr1orexpr2. Compare that to anif-else statement, which has no value. A statement often contains one or more expressions, but an expression can't directly contain a statement.Dart tools can report two kinds of problems:warnings anderrors. Warnings are just indications that your code might not work, but they don't prevent your program from executing. Errors can be either compile-time or run-time. A compile-time error prevents the code from executing at all; a run-time error results in anexception being raised while the code executes.
Additional resources
#You can find more documentation and code samples in thecore library documentation and theDart API reference. This site's code follows the conventions in theDart style guide.
Unless stated otherwise, the documentation on this site reflects Dart 3.10.0. Page last updated on 2025-11-4.View source orreport an issue.