Dart Tutorial

Dart Beginner Lesson 6 of 107 5 min read

Dart vs JavaScript: Key Differences Explained with Code

Dart vs JavaScript compared side by side: types, null safety, variables, strings, classes, async await, performance and when to choose each. Easy examples.

On this page

If you know JavaScript, Dart will feel familiar within an hour. The syntax looks alike, both have async and await, and both run in the browser. The big difference is that Dart checks types before your program runs, which catches many bugs early. This page shows the same ideas in both languages so you can map what you already know.

At a glance

DartJavaScript
TypesStatic and sound, with type inferenceDynamic (TypeScript adds static types)
NullSound null safety: String can never be nullAny value can be null or undefined
Runs onNative machine code, the Dart VM, JavaScript and WebAssemblyBrowsers, Node.js, Deno, Bun
Main useFlutter apps for mobile, web and desktop; CLI and serverWebsites, web apps, Node.js servers
Equality== (no type coercion)=== recommended, == converts types
Integer division~/ operatorMath.floor(a / b)
ClassesClasses, mixins, interfaces, sealed classesClasses and prototypes
Package managerpub (pub.dev)npm

Variables

// JavaScript
let count = 1;
const name = 'Asha';
count = 'one'; // allowed: the type changes
void main() {
  var count = 1;          // count is an int from now on
  final name = 'Asha';
  // count = 'one';       // compile error: a String is not an int
  count = 2;
  print('$name $count');
}
Asha 2

final in Dart is like const in JavaScript: it cannot be reassigned. Dart’s const is stricter: the value must be known when the program is compiled. See final vs const.

Strings

JavaScript uses back-ticks for template strings. In Dart every string can interpolate.

const lang = 'Dart';
console.log(`I am learning ${lang}`);
void main() {
  const lang = 'Dart';
  print('I am learning $lang');
  print('It has ${lang.length} letters');
}
I am learning Dart
It has 4 letters

Numbers and equality

void main() {
  print(7 / 2);     // 3.5
  print(7 ~/ 2);    // 3
  print(1 == 1.0);  // true: same number
  // print(1 == '1');  // always false in Dart, and the analyzer warns you
  print(0.1 + 0.2); // same floating-point rules as JavaScript
}
3.5
3
true
0.30000000000000004

Dart never converts types when comparing, so there is no ===. '1' == 1 is simply false.

Null and undefined

JavaScript has two empty values, null and undefined, and any variable can hold them. Dart has only null, and only types ending in ? may hold it.

String? findUser(int id) => id == 1 ? 'Asha' : null;

void main() {
  print(findUser(1) ?? 'Guest');
  print(findUser(2) ?? 'Guest');
  print(findUser(2)?.length);
}
Asha
Guest
null

?? and ?. work the same way as in modern JavaScript. The difference is that Dart will not let you call .length on a String? without handling the null case first. Read Null safety in Dart.

Arrays and objects vs lists and maps

const nums = [1, 2, 3];
const doubled = nums.map(n => n * 2);
const user = { name: 'Asha', age: 21 };
void main() {
  final nums = [1, 2, 3];
  final doubled = nums.map((n) => n * 2).toList();
  final user = {'name': 'Asha', 'age': 21};

  print(doubled);
  print(user['name']);
}
[2, 4, 6]
Asha

A JavaScript array is a Dart List. A JavaScript object used as a dictionary is a Dart Map. For structured data with fixed fields, Dart code normally uses a class or a record instead. See Dart list methods.

Functions

function add(a, b) { return a + b; }
const square = x => x * x;
int add(int a, int b) => a + b;
int square(int x) => x * x;

void main() {
  print(add(2, 3));
  print(square(5));
}
5
25

Dart arrow functions can only hold a single expression. Dart also has named parameters built in: greet(name: 'Asha'). See Function parameters.

Classes

class Person {
  final String name;
  int age;

  Person(this.name, this.age);

  void birthday() => age++;

  @override
  String toString() => '$name ($age)';
}

void main() {
  final p = Person('Asha', 21);
  p.birthday();
  print(p);
}
Asha (22)

No new, no this. needed inside methods, and the constructor Person(this.name, this.age) fills the fields for you. Dart also has mixins, interfaces and sealed classes.

async and await

A JavaScript Promise is a Dart Future. The async / await keywords work the same way.

async function load() {
  const user = await fetchUser();
  console.log(`Hello, ${user}`);
}
Future<String> fetchUser() async {
  await Future.delayed(const Duration(seconds: 1));
  return 'Asha';
}

void main() async {
  print('Loading...');
  final user = await fetchUser();
  print('Hello, $user');
}
Loading...
Hello, Asha

Dart also has Stream, a built-in type for many values over time, similar to an async iterator. See async and await in Dart and Streams.

Which should you learn?

  • Building mobile apps for Android and iOS from one codebase: learn Dart, then Flutter.
  • Building websites and front-end web apps: JavaScript (and TypeScript) is the standard.
  • Both is fine. Many developers use JavaScript for the web and Dart for apps. Knowing one makes the other much easier.

Try it yourself

Take a small JavaScript function you have written before, such as one that filters an array of objects, and rewrite it in Dart using a List of Maps. Then rewrite it again with a small class instead of maps and notice how the editor now catches typos in field names.

Practise in the playground Updated