Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Dart (3.13)  Module 1 – Getting started: the SDK, a first program and the tools

What Dart is and where it runs

One Dart program can run on the Dart VM, as native machine code, as JavaScript or as WebAssembly. See it run three ways and set a package's language version.

  • Beginner
  • 10 minutes
  • Examples run with dart 3.13.5 and Python 3.14.8
  • By MySmartCoPilot
Free lesson, Pro answers: 10 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Explain what Dart is and which platforms one Dart program can run on
  • Distinguish a JIT run on the Dart VM from AOT, JavaScript and WebAssembly builds
  • Predict how an integer above 2^53 prints on the VM and in a JavaScript build
  • Determine a package's language version from its SDK constraint
What you’ll learn

What you will learn

  • Explain what Dart is and which platforms one Dart program can run on
  • Distinguish a JIT run on the Dart VM from AOT, JavaScript and WebAssembly builds
  • Predict how an integer above 2^53 prints on the VM and in a JavaScript build
  • Determine a package's language version from its SDK constraint
On this page

One Dart file printed 9007199254740993 on the Dart VM and 9007199254740992 after it was compiled to JavaScript. Same source, same SDK, two answers: that one digit is the quickest way to see what Dart is, a single language with several compilers behind it.

You will see where a Dart program can run, run one program on the VM, as JavaScript and as WebAssembly and explain the digit that differs, and read which version of the language a package gets from one line of its pubspec.yaml.

Dart is one typed language with several compilers

Dart is an open-source programming language from Google. Its own documentation calls it client-optimized: built for apps on phones, desktops and the web, where a fast edit-and-run cycle while you write and a fast start once you ship both matter. It is also the language of Flutter, the multi-platform toolkit for app interfaces, and it runs command-line tools and servers as well.

Three properties shape everything later in this track:

  • Static types that are sound. The compiler checks that a variable’s value always matches its type, and you can usually leave the type out because Dart infers it.
  • Null safety that holds at run time. A variable cannot hold null unless its type says so, and this sound null safety: Dart's guarantee that a value whose type is not nullable is never null, checked by the compiler and still true while the program runs. A type allows null only when it says so, as String? does. still holds while the program runs.
  • Managed memory. A garbage collector reclaims what the program no longer uses, so you never release memory by hand.

What makes Dart unusual is how many ways the same source can run. Step through what the SDK does with one file:

Interactive · step by step One Dart source, four ways to run it Step through what the SDK makes of one file, from a run while you write it to the builds you ship.
One Dart source, four ways to run it, step 6 of 6. Showing main.dart, Dart VM (JIT: compiled as it runs), Native executable (AOT: machine code), JavaScript (runs where JavaScript runs), WebAssembly (.wasm plus a loader), The Dart runtime. In focus: The Dart runtime.dart runcompile execompile jscompile wasmmain.dartDart VMJIT: compiled as it runsNative executableAOT: machine codeJavaScriptruns where JavaScript runsWebAssembly.wasm plus a loaderThe Dart runtime

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. One source file. You write one Dart file. Nothing in it says where it will run; the command you type decides that.
  2. Run it while you write. dart run hands the file to the Dart VM, which compiles it just in time, as it runs. The VM can recompile a changed part while the program keeps running, which is what hot reload uses.
  3. Ship a native file. dart compile exe compiles the program ahead of time into machine code for this processor, plus a small Dart runtime, in one file that starts quickly and runs without the SDK.
  4. Ship for a browser. dart compile js turns the same program into a JavaScript file that any browser or Node.js can run. Integers then become JavaScript numbers.
  5. Or as WebAssembly. dart compile wasm writes a WebAssembly module that uses the browser's garbage collector (WasmGC), plus a small JavaScript file that loads it.
  6. A runtime on every target. Whichever way the code runs, a Dart runtime runs with it; on native targets it is inside the executable or part of the VM. It manages memory with a garbage collector, runs the type checks that cannot happen at compile time, such as a cast, and manages isolates.

The Dart VM: The virtual machine that runs Dart programs from source during development, compiling them just in time; dart run uses it, and it makes hot reload and debugging possible. is the engine of development, and the other three are builds you ship. Whichever way the code runs, it needs a Dart runtime, which manages memory and performs the type checks that wait for run time, such as casts, so the guarantees above hold on every target.

The VM runs your code while you write it, and AOT builds ship it

While you write, dart run gives your file to the Dart VM, which compiles it as it runs. That is just-in-time compilation: Compiling code while the program runs, as the Dart VM does during development, so that changed code can be compiled again and swapped into the running program.: the VM can recompile a part you changed while the program keeps its state, which is what hot reload: Putting changed code into a program that is already running without restarting it, so it keeps its state; the Dart VM's just-in-time compiler makes it possible. in Flutter uses, and it collects the live data that Dart DevTools shows.

When the program is ready to ship, ahead-of-time compilation: Compiling a whole program to machine code before it runs, as dart compile exe does; the result starts quickly and runs without the Dart SDK on the system it was built for. turns the whole program into ARM or x64 machine code first. The overview puts it as “Your AOT-compiled app launches with consistent, short startup time”: nothing is left to compile when it starts. For the web, the SDK has two production compilers: one to JavaScript and one to WebAssembly with WasmGC: The garbage-collection extension of WebAssembly. dart compile wasm writes modules that rely on it, so they run only in browsers and runtimes that support it., the garbage-collection extension of WebAssembly.

dart compile takes the kind of output as a subcommand, and its documentation lists six:

Subcommand What it writes Runs on
exe One executable: machine code and a small Dart runtime The operating system and processor it was built for
aot-snapshot Machine code without a runtime That system, started with dartaotruntime
jit-snapshot The parsed program, plus code compiled during a training run That processor, started with dart run
kernel A portable .dill file of the parsed program Any system with the Dart SDK
js A .js file and its source map Browsers and Node.js
wasm A .wasm module, a companion .mjs JavaScript file and a source map Browsers with WasmGC, and Node.js

The executable runs where it was built: an exe made on a Mac runs on Macs with the same kind of processor. The kernel file is the portable one, at the price of a slower start.

Which browsers run the WebAssembly build

The WebAssembly page of dart.dev lists the minimum browsers for a dart2wasm build: Chrome or Edge 137, Safari 26.2 and Firefox 134 (147 for Flutter web). Older browsers need the JavaScript build.

Checkpoint

Check: What Dart is · JIT runs and AOT builds

  1. Question 1 of 2 Which of these does every Dart program need while it runs, whether on the VM, as an executable, as JavaScript or as WebAssembly?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: A Dart runtime, which manages memory and runs the type checks left for run time

    The overview of Dart says that executing code always requires a Dart runtime: it manages memory with a garbage collector, enforces the type checks that happen at run time, such as casts, and manages isolates.

  2. Question 2 of 2 A teammate has the Dart SDK on a computer whose system and processor you do not know. Which one file of your program will run there?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The .dill file from dart compile kernel, started with dart run

    Of the formats in the table, only kernel is portable: one .dill runs with dart run wherever the SDK is installed, at the price of a slower start than machine code.

The same program can print two different answers

Here is the program from the start of this lesson. It adds 1 to 2^53, divides 1 by 3, and asks whether the sum is even:

three/main.dart: one program for three compilers Dart · three/main.dart
// One program for three compilers: the Dart VM, dart2js and dart2wasm.
void main() {
  const big = 9007199254740992; // 2 to the power 53
  final next = big + 1;
  print('2^53 + 1 = $next');
  print('1 / 3 = ${1 / 3}');
  print('next is even: ${next.isEven}');
}

Output

2^53 + 1 = 9007199254740993
1 / 3 = 0.3333333333333333
next is even: false

Recorded with Dart SDK 3.13.5 (stable) on macos_arm64 on macOS 26 arm64. To run it yourself: dart run main.dart

That run was the Dart VM. The next session builds the same file twice more, once with dart compile js and once with dart compile wasm, and runs both builds with Node.js. The small loader it uses for the WebAssembly build is the second file:

three/run_wasm.mjs: loads the WebAssembly build in Node.js JavaScript · three/run_wasm.mjs
// Runs the WebAssembly build of main.dart in Node.js: compile the module,
// instantiate it with the companion runtime main.mjs, then call main.
import { readFile } from 'node:fs/promises';
import { compile } from './out/main.mjs';

const bytes = await readFile(new URL('./out/main.wasm', import.meta.url));
const app = await compile(bytes);
const instance = await app.instantiate({});
instance.invokeMain();
The same main.dart on the VM, as JavaScript and as WebAssembly Python · three_ways_session.py
from session import files, run

# The same main.dart on the Dart VM, as JavaScript and as WebAssembly (both run by Node.js).
files("three/main.dart=main.dart", "three/run_wasm.mjs=run_wasm.mjs")
run(
    """
dart run main.dart
dart compile js -O2 -o out/main.js main.dart
node out/main.js
dart compile wasm -O2 -o out/main.wasm main.dart
node run_wasm.mjs
"""
)

Output

$ dart run main.dart
2^53 + 1 = 9007199254740993
1 / 3 = 0.3333333333333333
next is even: false
$ dart compile js -O2 -o out/main.js main.dart
Compiled 10,737,774 input bytes (5,318,344 characters source) to 5,253 characters JavaScript in … seconds
$ node out/main.js
2^53 + 1 = 9007199254740992
1 / 3 = 0.3333333333333333
next is even: true
$ dart compile wasm -O2 -o out/main.wasm main.dart
Generated wasm module 'out/main.wasm', and JS init file 'out/main.mjs'.
$ node run_wasm.mjs
2^53 + 1 = 9007199254740993
1 / 3 = 0.3333333333333333
next is even: false

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 three_ways_session.py

Side by side, the three runs printed this, and 1 / 3 came out as 0.3333333333333333 on all of them:

Target 2^53 + 1 next.isEven
Dart VM (dart run) 9007199254740993 false
JavaScript build, in Node.js 9007199254740992 true
WebAssembly build, in Node.js 9007199254740993 false

Only the JavaScript build lost the 3, and with it the program’s logic changed: it called an odd sum even. On native platforms an int is a signed 64-bit integer. JavaScript has one kind of number, a 64-bit floating-point value, so when Dart compiles to JavaScript both int and double become that number, and Dart’s number documentation states the consequence: an integer on the web keeps 53 bits of precision, and 2^53 and 2^53 + 1 map to the same value. The WebAssembly build printed the VM’s answer on this run. The division is the same everywhere, because a double is the same 64-bit floating-point format on every target.

Expecting a JavaScript build to stop at a number it cannot hold

It does not stop. The JavaScript build above turned 2^53 + 1 into 2^53 with no error and no warning, and the check after it used the rounded value: next.isEven answered true for an odd number. A run that ends normally says nothing about integers above 2^53; only the values it printed do, and here one of them was wrong.

The rounding is not limited to one value. Dart’s number page lists more expressions that differ on the web: 2^62 prints as 4611686018427387904 on native platforms and as 4611686018427388000 on the web, and 2^63, which wraps to -9223372036854775808 on native platforms, prints as 9223372036854776000 there. From −2^53 to 2^53, every integer is exact on every target.

Key idea

The same source can print different numbers on different targets: an int is a 64-bit integer on the VM, but a JavaScript build stores it as a 64-bit floating-point number, which can round integers above 2^53 without an error.

Checkpoint

Check: Integers in a JavaScript build

  1. Question 1 of 2 In the session, which target printed 9007199254740992 for 2^53 + 1?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The JavaScript build run by Node.js

    Dart's number documentation says that on the web an int is a double-precision floating-point value with no fractional part, which keeps 53 bits of integer precision, so 2^53 and 2^53 + 1 map to the same value.

  2. Question 2 of 2 Why did 1 / 3 print 0.3333333333333333 on all three targets?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: A double is the same 64-bit floating-point format on every target

    Integers differ on the web because JavaScript has no separate integer type. A double is the same 64-bit floating-point format on every target, so 1 / 3 gave the same double, and printed the same digits, on all three.

Your SDK constraint chooses the language version

Every minor release of the SDK is also a version of the language, written with two numbers, such as 3.13. The Dart 3.13.5 SDK reads code at any language version from 3.13 back to 2.12, the first with null safety, and it picks one for each library. A package’s SDK constraint: The environment sdk entry of pubspec.yaml, such as ^3.13.0: the Dart SDK versions a package works with. Its lower bound also sets the package's language version. decides: the lower bound of environment: sdk: in pubspec.yaml is the package’s language version: The version of the Dart language a library is read with, written as major.minor, such as 3.13. A package's default is the lower bound of its SDK constraint.. sdk: ^3.12.0 means language 3.12, even on a newer SDK.

That is how a new feature arrives without breaking old code. Walk through what each Dart 3 release changed:

Timeline · 14 events in order What each Dart 3 release changed in the language Walk through the releases in order; a package can use a release's new features only when its SDK constraint starts at that release or later.
  1. Dart 3.0

    Records, patterns and class modifiers new syntax

    Records bundle several values without a class, patterns take them apart, switch becomes an expression, and sealed, final, base and interface classes arrive. Sound null safety is always on from this release.

  2. Dart 3.1

    No language changes

    The changelog of this release lists library and tool changes only, so language 3.1 reads code as 3.0 does.

  3. Dart 3.2

    Private field promotion analysis

    A private final field, such as _name, can now be promoted by a null check or an is test, so code inside an if that checked it no longer needs a ! after it.

  4. Dart 3.3

    Extension types new syntax

    An extension type gives an existing type a new static interface at no cost at run time, for example a Meters type that is an int underneath.

  5. Dart 3.4

    Sharper type analysis analysis

    The types of conditional expressions, if-null expressions such as a ?? b, and switch expressions are worked out more precisely.

  6. Dart 3.5

    Two small inference changes analysis

    No new features. Type inference on the operand of await and on the right side of ?? now matches between the compiler and the analyzer, which the changelog expects to make little or no difference in practice.

  7. Dart 3.6

    Digit separators new syntax

    Underscores may separate the digits of a number literal, so one million can be written 1_000_000.

  8. Dart 3.7

    Wildcard variables and the tall style new syntax

    A local variable or parameter named _ declares nothing, so several of them can share the name. dart format uses its new tall style for code at language version 3.7 or later.

  9. Dart 3.8

    Null-aware elements new syntax

    Writing ?value inside a list, set or map literal adds the element only when the value is not null.

  10. Dart 3.9

    Null safety assumed by flow analysis analysis

    Type promotion, reachability and definite assignment now assume null safety, which gives more precise results and can report more dead code.

  11. Dart 3.10

    Dot shorthands new syntax

    Where the type is known from the context, a static member can be named without its type, as in .blue instead of Color.blue.

  12. Dart 3.11

    No language changes

    A release of library and tool changes only, so its language version reads code exactly as 3.10 does.

  13. Dart 3.12

    Private named parameters new syntax

    A named parameter written this._x now sets the private field _x directly, while callers still pass it under the public name, as in Point(x: 1); before 3.12 that parameter was an error.

  14. Dart 3.13

    Primary constructors new syntax

    A class can declare its constructor and its fields in its header, as in class Point(var int x, var int y); a shorter way to write what was already possible.

The timeline has 14 events, from Dart 3.0 to Dart 3.13.

Primary constructors, the 3.13 feature, make a good test. The next session runs the same file in two packages, the first with sdk: ^3.12.0 and the second with sdk: ^3.13.0:

One file under language 3.12 and under language 3.13 Python · versions_session.py
from session import files, run

# The same file in two packages: one says sdk: ^3.12.0, the other sdk: ^3.13.0.
files("versions/pc312=points_312", "versions/pc313=points_313")
run(
    """
cat points_312/pubspec.yaml
cd points_312
dart pub get --offline
!dart run bin/points.dart
cd ../points_313
dart pub get --offline
dart run bin/points.dart
"""
)

Output

$ cat points_312/pubspec.yaml
name: points_312
environment:
  sdk: ^3.12.0
$ cd points_312
$ dart pub get --offline
Resolving dependencies...
Downloading packages...
Got dependencies!
$ dart run bin/points.dart
bin/points.dart:2:13: Error: The 'primary-constructors' language feature is disabled for this library.
Try removing the package language version or setting the language version to 3.13 or higher.
class Point(var int x, var int y);
            ^^^
bin/points.dart:2:24: Error: The 'primary-constructors' language feature is disabled for this library.
Try removing the package language version or setting the language version to 3.13 or higher.
class Point(var int x, var int y);
                       ^^^
bin/points.dart:2:12: Error: The 'primary-constructors' language feature is disabled for this library.
Try removing the package language version or setting the language version to 3.13 or higher.
class Point(var int x, var int y);
           ^
bin/points.dart:2:34: Error: The 'primary-constructors' language feature is disabled for this library.
Try removing the package language version or setting the language version to 3.13 or higher.
class Point(var int x, var int y);
                                 ^
[exit status 254]
$ cd ../points_313
$ dart pub get --offline
Resolving dependencies...
Downloading packages...
Got dependencies!
$ dart run bin/points.dart
x = 3, y = 4

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 versions_session.py

Under 3.12 the compiler refused with “The ‘primary-constructors’ language feature is disabled for this library” and exit status 254, the status the dart command uses for a compile-time error. Under 3.13 the same file printed x = 3, y = 4. One file can also choose for itself: a // @dart = 3.12 comment before any code reads that library as language 3.12, while the rest of the package keeps its own version.

The versions this track runs

Every example here ran on the Dart SDK 3.13.5, a stable release, and the JavaScript and WebAssembly builds ran in Node.js 24.21.0. The Dart team supports only the latest stable release and publishes a new one about every three months, so compare dart --version with 3.13.5 when your output differs from the page.

Checkpoint

Check: Language versions

  1. Question 1 of 2 A package's pubspec says sdk: ^3.12.0 and you run it with the Dart 3.13.5 SDK. Which language version are its files read with?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: 3.12, the lower bound of the constraint

    An SDK reads every language version up to its own, back to 2.12 for a Dart 3 SDK. It reads each package at the version the package asks for, which is the lower bound of environment sdk in pubspec.yaml.

  2. Question 2 of 2 How does one file of a 3.13 package ask to be read as language 3.12?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: With a // @dart = 3.12 comment before any code in the file

    The comment must be a // comment and must come before any Dart code, though other comments may come before it. Whitespace inside it does not matter except within the @dart and version strings.

Practise: read the platform and the version

Work through these, then answer the questions below:

  1. Change big + 1 to big + 2 in three/main.dart and predict all three lines of each target before you look back at the table. Every integer up to 2^53 has a JavaScript number of its own; between 2^53 and 2^54 only the even ones do.
  2. A pubspec says sdk: '>=3.7.0 <4.0.0'. Write down its language version, and which features of the timeline it can and cannot use.
  3. A colleague’s file starts with // @dart = 3.9. Name one feature from the timeline that file cannot use.

The questions come one at a time, with the weakest idea first:

Practice that adapts to you

Practise this lesson

8 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 8 What does sound in sound null safety promise?

    Choose one answer.

    Show the answer: Question 1 of 8

    Answer: A variable whose type is not nullable can never hold null, even while the program runs

    Dart is non-nullable by default, and its type system is sound: when it decides an expression cannot be null, that holds at run time too. Dart has enforced this since Dart 3.

  2. Question 2 of 8 An AOT-compiled program casts a value with as and the value has another type. What reports the failure, and when?

    Choose one answer.

    Show the answer: Question 2 of 8

    Answer: The Dart runtime inside the executable, while the program runs

    Most type checks are static. The ones that depend on a value, such as as casts and is tests, happen at run time, and every target's Dart runtime performs them.

  3. Question 3 of 8 Which way of running Dart makes hot reload possible?

    Choose one answer.

    Show the answer: Question 3 of 8

    Answer: The Dart VM's just-in-time compiler, which can recompile changed code in a running program

    The VM compiles code as it runs and can compile it again when it changes. Flutter's debug mode and dart run use it; release builds are compiled ahead of time.

  4. Question 4 of 8 A teammate wants one file of your tool that runs on Windows, macOS and Linux laptops, all of which have the Dart SDK. What do you suggest, and what does it cost?

    Choose one answer.

    Show the answer: Question 4 of 8

    Answer: A kernel file, which runs on any system with the SDK, at the price of a slower start than AOT output

    dart compile kernel writes a .dill file of the program that dart run starts on every operating system and processor. When start-up time matters, build one exe per system instead.

  5. Question 5 of 8 How many bits of integer precision does an int keep when Dart is compiled to JavaScript?

    Type a number.

    Show the answer: Question 5 of 8

    Answer: 53 bits

    A JavaScript number is a 64-bit double, whose 53-bit significand holds every integer up to 2^53 exactly. On native platforms an int is a 64-bit integer with 63 bits for the value and one for the sign.

  6. Question 6 of 8 A web build compiled to JavaScript keeps a running count in an int and adds 1 to it each time. What happens once the count reaches 2^53, 9007199254740992?

    Choose one answer.

    Show the answer: Question 6 of 8

    Answer: It stays at 9007199254740992, because each + 1 rounds back to the same number, and nothing reports an error

    Every integer up to 2^53 has its own JavaScript number, so the count is exact until it gets there. The next one, 2^53 + 1, maps to 2^53, so adding 1 gives the same value again and the count stops growing. On the VM the same code keeps counting until 2^63 - 1.

  7. Question 7 of 8 A pubspec says sdk: '>=3.10.0 <4.0.0'. Which of these can its code use?

    Choose one answer.

    Show the answer: Question 7 of 8

    Answer: Dot shorthands, but not private named parameters

    Read the lower bound of the constraint: 3.10. Every feature of the timeline up to and including 3.10 is there, and nothing later, whatever SDK runs the package.

  8. Question 8 of 8 The SDK moves from 3.13.0 to 3.13.5. What can that change in the language?

    Choose one answer.

    Show the answer: Question 8 of 8

    Answer: Nothing; a patch release stays language version 3.13 and may only fix bugs

    Each minor release of the SDK is a new language version. Patch releases, such as 3.13.5, fix bugs in the tools and libraries and keep the language exactly as it was.

Interview questions

Warm-up (fresher): What is the difference between JIT and AOT compilation in Dart?

Just-in-time compilation happens while the program runs: the Dart VM compiles code as it is needed, which lets it recompile a changed function and keep the program’s state, the basis of hot reload, and it gives debuggers and DevTools a live program to inspect. dart run and Flutter’s debug mode use it. Ahead-of-time compilation happens before the program runs: dart compile exe or a Flutter release build for Android or iOS turns the whole program into machine code for one operating system and processor, with a small Dart runtime for garbage collection and type checks. The AOT result starts quickly and the same way every time, and the machine that runs it needs no SDK, but it cannot be changed while it runs. So use JIT while you develop and AOT for what you ship.

Two longer questions of this module start from this lesson:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to mid

    Order ids in your Dart backend are 64-bit integers, and the same model code now runs in a web build compiled to JavaScript. Users report that some ids shown in the browser differ from the database by one or two. What is happening, and how do you fix it without breaking the native apps?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to senior

    Your package says sdk: ^3.6.0, and a teammate raises it to ^3.13.0 to use primary constructors. The change touches one line of pubspec.yaml, yet the format check now fails and the analyzer reports new warnings. Why, and how should such an upgrade be done?

    Model answer, Pro. First step and follow-ups

Flashcards · 7 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. What kind of language is Dart, and where can one Dart program run?

    An open-source, statically and soundly typed, garbage-collected language from Google. The same program can run on the Dart VM, as native machine code, as JavaScript and as WebAssembly.

  2. What is the difference between JIT and AOT compilation in Dart?

    JIT compiles while the program runs on the Dart VM, so dart run and hot reload can recompile changed code and keep the program's state. AOT turns the whole program into machine code for one system before it runs: it starts quickly and needs no SDK, but cannot change while it runs.

  3. Which six kinds of output can dart compile write?

    exe (machine code with a small Dart runtime), aot-snapshot (machine code without a runtime), jit-snapshot, kernel (a portable .dill file), js (a .js file with a source map) and wasm (a .wasm module with a companion .mjs file and a source map).

  4. Which dart compile output runs on any system that has the Dart SDK?

    The kernel file (.dill), at the price of a slower start. An exe runs only on the operating system and processor it was built for, so one made on a Mac runs on Macs with the same kind of processor.

  5. One program printed 2^53 + 1 on the Dart VM, in a JavaScript build and in a WebAssembly build. What did each print?

    9007199254740993 on the VM and in the WebAssembly build, 9007199254740992 in the JavaScript build. JavaScript stores a Dart int as a 64-bit floating-point number, which rounds integers above 2^53 without an error.

  6. What chooses a Dart package's language version?

    The lower bound of the SDK constraint in its pubspec.yaml. A // @dart = x.y comment at the top of a file changes it for that one file; a 3.12 package refused the 3.13 primary constructor that a 3.13 package ran.

  7. Which browsers can run a dart2wasm build?

    dart.dev lists Chrome or Edge 137, Safari 26.2 and Firefox 134 (147 for Flutter web) as the minimum versions, because the build needs WasmGC. Older browsers need the JavaScript build.

Key takeaways

  • Dart is an open-source, statically and soundly typed, garbage-collected language from Google that runs on the Dart VM, as native machine code, as JavaScript and as WebAssembly.
  • The VM compiles just in time while you develop, which enables hot reload; dart compile makes the ahead-of-time, JavaScript and WebAssembly builds you ship, and each of them still runs with a Dart runtime.
  • On the web through JavaScript, an int is a 64-bit floating-point number with 53 bits of integer precision, so the JavaScript build printed 9007199254740992 where the VM and the WebAssembly build printed 9007199254740993.
  • The lower bound of a package’s SDK constraint is its language version, a // @dart = x.y comment changes it for one file, and the 3.12 package refused the 3.13 primary constructor that the 3.13 package ran.

Terms in this lesson

ahead-of-time compilation
Compiling a whole program to machine code before it runs, as dart compile exe does; the result starts quickly and runs without the Dart SDK on the system it was built for.
Dart VM
The virtual machine that runs Dart programs from source during development, compiling them just in time; dart run uses it, and it makes hot reload and debugging possible.
hot reload
Putting changed code into a program that is already running without restarting it, so it keeps its state; the Dart VM's just-in-time compiler makes it possible.
just-in-time compilation
Compiling code while the program runs, as the Dart VM does during development, so that changed code can be compiled again and swapped into the running program.
language version
The version of the Dart language a library is read with, written as major.minor, such as 3.13. A package's default is the lower bound of its SDK constraint.
SDK constraint
The environment sdk entry of pubspec.yaml, such as ^3.13.0: the Dart SDK versions a package works with. Its lower bound also sets the package's language version.
sound null safety
Dart's guarantee that a value whose type is not nullable is never null, checked by the compiler and still true while the program runs. A type allows null only when it says so, as String? does.
WasmGC
The garbage-collection extension of WebAssembly. dart compile wasm writes modules that rely on it, so they run only in browsers and runtimes that support it.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.