Documentation

Data Classes

data class for anything that crosses a boundary — the network, disk, a navigation argument. state class for anything that only exists while the app is running.

data class

A data class is annotated for you. It comes out @Serializable for JSON and @Parcelize for Android, and implements Parcelable:

data class User(val id: String, val name: String)
@Serializable
@Parcelize
data class User(val id: String, val name: String) : Parcelable

Which is why $fetch can decode straight into one, and why $navigate can carry one as state without you writing a converter:

data class Show(val id: String, val title: String)

val shows: List<Show> = $fetch.get(url = "…/shows")
$navigate("/show/${show.id}", state = { title: show.title })

state class

Some state cannot be serialized and should not pretend otherwise — a lambda has no JSON form. state class is a plain Kotlin data class with no annotations attached:

state class DialogConfig(
    val title: String,
    val onConfirm: () -> Unit,
    val onDismiss: () -> Unit
)

Declaring that as a data class would be a compile error the moment the serializer reached onConfirm. state class says up front that this value lives and dies in memory.

See it happen

One keyword, three annotations — flip between them and watch the Kotlin change.

ShowCard.wh
data class Show(val id: String, val title: String)

val show = Show("1", "Numberwang")

<Text>{show.title}</Text>
Kotlin waiting
Scroll into view to compile.

data class picks up @Serializable and @Parcelize automatically, plus : Parcelable — it is ready to cross a network call or a navigation argument.

KeywordGetsUse for
data class@Serializable + @ParcelizeAPI responses, stored records, navigation arguments
state classPlain Kotlin data classUI state, callbacks, anything holding a lambda
If you are unsure, ask whether the value would survive being written to disk and read back. If yes, data class. If it holds a function, a Context, or a stream, it is a state class.

Where they live

Both work anywhere, but src/models/ is the conventional home for the ones shared across screens, reachable as $app.models.User. See Project Structure.

import $app.models.User

Annotations are case-insensitive

If you want to be explicit about something the shorthand already implies, spelling is loose:

@Serializable   // or @serializable, @Serialize, @serialize
@Parcelize      // or @parcelize, @Parcel, @parcel

See Also