Side-by-side, interactive cheatsheets for Dart programmers
comparing Dart to other languages. Every example runs live in your browser — no
setup, no installation.
Choose your own path by reordering languages
Every static guarantee traded for expressiveness. No compiler, no type annotations, no null safety — and in return, a language where numbers are objects, blocks are everywhere, classes are never closed, and methods can be written while the program runs. Dart checks your work up front; Ruby hands you the keys.
NoMethodError when that line finally runs3.times, nil.to_s, 1 + 2 is 1.+(2) — with no primitives and no non-method operatorsnil is an object (not Dart's tracked null), only nil and false are falsy (so 0 and "" are truthy), and &./|| stand in for ?./??each, map, and File.open { } are ordinary methods taking a block, and Enumerable is the richest collection library on this site:name), ranges (1..5), and &:method shorthand are newsend/define_method/method_missing rewrite the object model at run timeNot a sibling — a deliberately small language that rejects most of what Dart is built on. No classes or inheritance, no exceptions, no sound null safety, no named or optional arguments, no ternary. What you get back is a language you can hold in your head, an instant compiler, and goroutines and channels: cheap threads over shared memory, a different bet than Dart's single thread plus copy-only isolates.
(value, error) and you check if err != nil at every call site — explicit where Dart propagates a throw automaticallyimplements)nil and zero values replace it, and a nil dereference compiles then panics — the bug class Dart eliminates*T, &x), where every Dart type is a reference; a method needs a pointer receiver to mutatefor is the only loopgo func() plus a sync.Mutex or a channel replaces Dart's isolates — data races are possible and yours to guardDart's closest sibling — so close the danger is complacency. Null safety, C-family syntax, when/switch, named arguments, sealed classes, extension functions, string interpolation, and structured concurrency all rhyme. This page leads with where the rhyme misleads: real threads with shared memory, renamed null operators, and a JVM soundness hole Dart never has.
Dispatchers.Default runs coroutines in parallel over one heap, so data races and Mutex are back?? is Elvis ?:, single-bang ! is double-bang !!, and late splits into lateinit and by lazydata class is the gift Dart lacks: free equals/hashCode/toString/copy/destructuring — but it is a reference and copy() is shallow, just like a Dart classInt/Long/Double/Float) with no num supertype and no ~/ — / on two Ints already truncates..) become scope functions (apply/also), named constructors become companion object factories, and mixins become interface delegation (by)The sharpest contrast on the site: none of Dart's runtime conveniences, all replaced by compile-time guarantees. Ownership and borrowing replace the garbage collector, Option replaces null, Result and ? replace exceptions, let is immutable by default, and there are no classes — structs, traits, and exhaustive match instead.
& (shared) or &mut (exclusive) — "shared XOR mutable" makes data races a compile errorOption<T> (Some/None) with match, if let, unwrap_or, and ? — a step beyond even Dart's sound null safety, since there is no null to dereferenceResult<T, E> (Ok/Err) with the ? propagation operator; panic! is only for unrecoverable bugslet is fixed, let mut opts into mutation (the reverse of Dart's var)impl blocks add methods, traits are the interfaces and mixins (default methods), enums carry data, and #[derive] gives you Kotlin's data-class conveniences à la carte<T: PartialOrd>) — no boxing, no run-time cost — and real threads share memory safely via Arc/Mutex rather than Dart's copy-only isolatesDart's other close sibling — optionals, ??, force-unwrap !, protocols, extensions, trailing closures, async/await, and rich pattern matching all rhyme. So this page leads with the real gaps: Swift has value types (struct, and even arrays, copy on assignment), reference counting instead of a garbage collector, and enums that finally carry payloads.
struct — and Array/Dictionary/Set/String — copies on assignment, where every Dart type is a reference; let freezes the whole value and mutating methods need mutating + a vardeinit, so retain cycles leak and you break them with weak/unowned — a discipline Dart's collector hidessealed class becomes one enum with payloads — the exact feature Dart's enum cannot express?, ??, !, ?.) but unwrap via if let/guard let; late becomes lazy var or an implicitly-unwrapped !move(x: 3, y: 4)), / on two Ints truncates with no implicit numeric conversion, and interpolation is \(expr)inits, and top-level code runs with no main()The same C-family, null-safe, async-first look — but the safety underneath is gradual, not sound. ?., ??, string interpolation, arrow bodies, and async/await all map almost 1:1 from Dart — until !, as, and any turn out to be compile-time lies the checker permits, where Dart's check at run time.
strictNullChecks) but is not sound: ! and as are erased, unchecked assertions — a wrong one yields a quiet undefined, not the exception Dart throwsnull AND undefined — an optional field is T | undefined, and == null is the check that catches bothimplements needed), generics vanish at run time, and is List<int> has no equivalentreturn this, static factories, and mixin functionssealed + exhaustive pattern switch becomes a discriminated union with a never-based exhaustiveness check; Dart 3 record/list patterns have no analogPartial, Pick, keyof, infer) compute types from types — the one corner where TypeScript out-expresses Dart's generics entirelyDart's closest cousin — same C-family syntax, static typing, GC, OOP, and async/await. (Anders Hejlsberg had a hand in both C# and TypeScript.) So this page is about where the rhyme diverges: value types, an unsound take on nullable references, records that mean something different, LINQ, delegates and events, and no mixins or cascade.
struct (and record struct) copies on assignment, where every Dart type is a reference — class stays reference-typed like Dart! is an unchecked forgiveness that can still throw NullReferenceExceptionrecord is a class with generated value equality and with expressions (Kotlin's data class), not Dart's tuple-style record — a genuine false friend{ get; set; init; }) are the everyday getters/setters, and primary constructors keep classes terseWhere/Select/GroupBy, deferred) out-reaches Dart's Iterable API; delegates (Func/Action) and first-class events have no direct Dart analogout/in) on top