kt.dart — Kotlin like collections for your Flutter business logic

No matter how great Flutter is, using Dart feels like a step backwards when coming from Kotlin. I understand the reasoning why Dart was chosen as Flutters language but I miss Kotlins feature rich standard library. That’s why I decided to port it to Dart. Welcome kt.dart!

kt.dart doesn’t introduce new language features but it would definitely benefit from some. That’s why I invite you to upvote some of my favorites Dart language proposals: Extension Methods, Optional Semicolons, Non-Nullable types, Destructuring Declarations, Data Classes

Dart’s missing high-level collections for business logic

The most common collection in nearly every programming language is the array. Dart doesn’t have arrays, Dart arrays are Lists. And Dart’s Lists are amazing compared to Java’s Array. But is such a comparison justifiable? Shouldn’t Dart’s List better be compared with Java’s ArrayList or Kotlins MutableList?

Neither of those comparisons are fair. The most important aspect is that there is a right tool for the job.

My job is to write business logic and SDK with stable APIs. This is much more challenging in Dart compared to Kotlin. Especially Dart’s collections aren’t perfect for the job. That’s why I ported Kotlins high-level collections to Dart, allow me to write better APIs.

Before I jump into kt.darts API, I’d like to show where Dart’s collections are lacking compared to kotlins collections:

Explicit immutability

Using Kotlin made me used to immutability. My entities are immutable (data classes) and so are the Lists I return from my APIs. Immutable entities aren’t a problem in Dart. But a immutable List has the same API as a modifiable List. Consumers might expect to be able to mutate a immutable List. There is no compiler warning, it crashes at runtime.

There is also no way to test if a List is modifiable or not. Unlike Kotlin, Dart doesn’t differentiate between List and MutableList.

Deep Equality

Comparing two Dart collections (List, Set or Map) doesn’t compare their contents, it only checks their identity. Dart offers a solution: The equality functions in the collection package.

But Dart’s collections don’t use DeepCollectionEquality for their equals checks internally, which makes methods like List.contains or Map.containsValue unusable.


Dart doesn’t offer collections which are deep equal and differentiate between immutable and mutable collections. Since it doesn’t exists kt.dart is here to fill the void.

kt.dart: collection

kt.darts collection package offers immutable collections (KtList, KtSet, KtMap) with a correct equals implementation.

This is similar to built_value, but it doesn’t stop there. kt.dart collections also offers mutable types. Only the mutable types offer mutation methods. Nobody can accidentally try to mutate an immutable collection.

KtIterable doesn’t extend Dart’s Iterable

Unlike built_value, kt.dart collections don’t extend Dart’s Iterable. The reason for this is that Dart’s naming of methods is uncommon. Modern languages (Kotlin, Swift, TypeScript) all named their Iterable methods the same (map,flatMap, filter, …). This helps a lot when working with developers from different platforms. Dart’s expand or where is less common.

The minor downside of not extending Iterable is that for loops don’t work out of the box. To solve this, each KtIterable exposes a Dart Iterable via iter. A for loop then looks like this:

150+ methods

Additionally, kt.dart collections comes with over 150 methods out of the box. All of them can be easily discovered via auto-completion.

Checkout the documentation to discover more methods. Or just start using it. Here are some of my favorites:

Notice that collections can be created by either a function listOf(1, 2, 3), listFrom([1, 2, 3]) (Kotlin style) or a constructor call List.of(1, 2, 3), List.from([1, 2, 3]) (Dart style). Both versions are equally supported the usage depends on your personal taste.

Just the beginning

This is just the beginning of kt.dart. The collection module is the first (and most important) part. But I can already think about more modules. For example ranges,sequences or text.