Anatomy of a Dart file
Dart is a client-optimized language for fast apps on any platform, most notably used for Flutter development.
File extensions: .dart
Every part of the example below is labelled and explained. This page is one of 55 annotated tours on AnatomyOf, a free, open-source project by LunarWerx Studios.
What is inside a Dart file
Comment
Single-line (//) or documentation (///), ignored by the compiler.
A double slash starts a comment that runs to the end of the line, the same as in C, Java, or JavaScript. Dart also supports block comments with /* ... */, which unlike some C-family languages are allowed to nest inside one another. A triple-slash comment placed directly above a declaration is a documentation comment. Tools like dart doc collect these and render them as API documentation, and the first sentence is treated as a short summary shown in IDE tooltips and search results.
Import statement
Brings in other libraries or files.
import 'dart:math' brings in a core library that ships with the Dart SDK; import 'package:flutter/material.dart' brings in a library from an external package declared in pubspec.yaml; and a relative import like import 'src/helper.dart' reaches another file in the same project. An import can be narrowed with show or hide to control which names it exposes, and given a prefix with as when two libraries export a name that would otherwise collide.
Top-level variable/constant
Defined outside any class or function using var, final, or const.
A name declared with var can be reassigned, final can be set only once and then never reassigned, and const must be a compile-time constant. Its value is fixed before the program even runs. const double pi = 3.14159 is baked into the compiled output, while a final value can still be computed at runtime. Top-level declarations like this live outside any class or function and are visible throughout the library (file) that defines them, unless the name is prefixed with an underscore, which makes it private to that library.
Class definition
A blueprint for objects, introduced with class.
Every piece of data in Dart is an object, including numbers and functions, and class is how you define a new type of object. A class groups together fields (its data) and methods (its behavior) under one name, and other code creates instances of it by calling a constructor. Dart classes support single inheritance with extends, interfaces implicitly (any class can be used as an interface via implements), and composable behavior through mixin and with, which lets a class reuse a chunk of functionality without fitting it into a strict inheritance chain.
Field (instance variable)
Data stored within an object.
A field declared inside a class body holds one value per instance of that class. Each Circle gets its own radius. Marking a field final means it can be set once, typically during construction, and never changed afterward, which is a common pattern for objects meant to be immutable. Dart's sound null safety means a field's type determines whether it can hold null: double radius must always have a value, while double? radius is explicitly allowed to be absent, and the compiler enforces the distinction at compile time rather than leaving it to a runtime crash.
Constructor
A special method used to create an object.
A constructor shares its class's name and runs when an object is created with Circle(5.0). The parameter this.radius is an initializing formal, shorthand that assigns the argument directly to the field of the same name without a separate assignment statement in the constructor body. Dart also supports named constructors like Circle.fromDiameter(...) for alternate ways to build an instance, and const constructors, which allow instances to be created as compile-time constants when every field is itself final and constant.
Method/function definition
A reusable block of code, defined with a return type and name.
A function or method is introduced by its return type (or void if it returns nothing), a name, and a parameter list in parentheses. double get area => ... is a getter (a method called like a property, without parentheses at the call site) and the arrow syntax (=>) is shorthand for a body that is a single expression, equivalent to { return ...; }. A method defined inside a class body implicitly receives access to the instance's other fields and methods; printDetails() can read radius and call area without qualifying them, because both belong to the same object.
String interpolation
Embeds expressions inside a string using $.
A dollar sign followed by a variable name, like $radius, substitutes that value directly into a string without concatenation. When the expression is more than a bare identifier (a method call, a property access, or an arithmetic expression) it must be wrapped in braces, as in ${area.toStringAsFixed(2)}. Interpolation works inside both single- and double-quoted strings, and Dart also supports raw strings (prefixed r) where $ and backslash escapes are treated literally, which is useful for regular expressions or file paths.
Main function
The entry point for a Dart application.
Every runnable Dart program has a top-level void main() function, which is where execution begins. For a command-line app it may accept List<String> args to read arguments passed on invocation; for a Flutter app, main() typically does very little itself beyond calling runApp(MyApp()) to hand control to the widget tree. Dart can run in two different modes: the Dart VM interprets and JIT-compiles code during development for fast iteration and hot reload, while dart compile (or Flutter's release build) ahead-of-time compiles main() and everything it reaches into native machine code for fast start
Object instantiation
Creates a new instance of a class.
Circle(5.0) calls the class's constructor to create a new object; modern Dart no longer requires the new keyword that older code used to write, though new Circle(5.0) still parses. Because every value is an object, this is the same mechanism used under the hood for built-in types like List and Map. Assigning the result to a final binding, as in final myCircle = Circle(5.0), means the variable itself cannot be reassigned to point at a different object, but it says nothing about whether the object's own fields can change.
Method/function call
Executes a function or method.
Dot notation invokes a method on an instance, as in myCircle.printDetails(), while a bare name like calculateCircumference(5.0) calls a top-level function directly. Arguments are matched positionally by default, but Dart also supports named arguments in braces, like Circle(radius: 5.0), which callers can supply in any order. Because everything is an object, even operators like + and * are method calls in disguise (2 * pi * r desugars to calls on num's multiplication operator) which is part of why Dart lets user-defined classes overload operators too.
Control flow (loop & conditional)
Executes code based on logic (for, if, else).
A C-style for (var i = 0; i < 3; i++) loop counts through a range, while if/else branches on a boolean condition. Dart's sound type system requires the condition to actually be a bool, unlike languages that treat 0 or null as falsy. i % 2 == 0 uses the modulo operator to test whether i is even. Dart also offers for-in to iterate any Iterable (such as a List), a while loop for a condition checked before each pass, and a do-while loop for one checked after, alongside break and continue for early exit or skipping an iteration.
Official Dart site · All languages on AnatomyOf
The interactive tour needs JavaScript. Enable it to hover a callout and trace it into the code.