[go: nahoru, domu]

Deprecate @Model

Relnote: “
@Model annotation is now deprecated. Use state and mutableStateOf as alternatives. This deprecation decision was reached after much careful discussion.

Justification
=============

Rationale includes but is not limited to:
- Reduces API surface area and concepts we need to teach
- More closely aligns with other comparable toolkits (Swift UI, React, Flutter)
- Reversible decision. We can always bring @Model back later.
- Removes corner-case usage and difficult to answer questions about configuring @Model as things we need to handle
  - @Model data classes, equals, hashcode, etc.
  - How do I have some properties “observed” and others not?
  - How do I specify structural vs. referential equality to be used in observation?
- Reduces “magic” in the system. Would reduce the likelihood of someone assuming system was smarter than it is (ie, it knowing how to diff a list)
- Makes the granularity of observation more intuitive.
- Improves refactorability from variable -> property on class
- Potentially opens up possibilities to do hand-crafted State-specific optimizations
- More closely aligns with the rest of the ecosystem and reduces ambiguity towards immutable or us “embracing mutable state”


Migration Notes
===============

Almost all existing usages of @Model are fairly trivially transformed in one of two ways. The example below has a @Model class with two properties just for the sake of example, and has it being used in a composable.

```
@Model class Position(
 var x: Int,
 var y: Int
)

@Composable fun Example() {
 var p = remember { Position(0, 0) }
 PositionChanger(
   position=p,
    p.x = it }
    p.y = it }
 )
}
```

Alternative 1: Use State<OriginalClass> and create copies.
----------------------------------------------------------

This approach is made easier with Kotlin’s data classes. Essentially, make all previously `var` properties into `val` properties of a data class, and then use `state` instead of `remember`, and assign the state value to cloned copies of the original using the data class `copy(...)` convenience method.

It’s important to note that this approach only works when the only mutations to that class were done in the same scope that the `State` instance is created. If the class is internally mutating itself outside of the scope of usage, and you are relying on the observation of that, then the next approach is the one you will want to use.

```
data class Position(
 val x: Int,
 val y: Int
)

@Composable fun Example() {
 var p by state { Position(0, 0) }
 PositionChanger(
   position=p,
    p = p.copy(x=it) }
    p = p.copy(y=it) }
 )
}
```

Alternative 2: Use mutableStateOf and property delegates
--------------------------------------------------------

This approach is made easier with Kotlin’s property delegates and the `mutableStateOf` API which allows you to create MutableState instances outside of composition. Essentially, replace all `var` properties of the original class with `var` properties with `mutableStateOf` as their property delegate. This has the advantage that the usage of the class will not change at all, only the internal implementation of it. The behavior is not completely identical to the original example though, as each property is now observed/subscribed to individually, so the recompositions you see after this refactor could be more narrow (a good thing).

```
class Position(x: Int, y: Int) {
 var x by mutableStateOf(x)
 var y by mutableStateOf(y)
}

// source of Example is identical to original
@Composable fun Example() {
 var p = remember { Position(0, 0) }
 PositionChanger(
   position=p,
    p.x = it }
    p.y = it }
 )
}
```
“

Bug: 156546430
Bug: 152993135
Bug: 152050010
Bug: 148866188
Bug: 148422703
Bug: 148394427
Bug: 146362815
Bug: 146342522
Bug: 143413369
Bug: 135715219
Bug: 126418732
Bug: 147088098
Bug: 143263925
Bug: 139653744

Change-Id: I409e8c158841eae1dd548b33f1ec80bb609cba31
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameDiagnosticTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameDiagnosticTests.kt
index 74fb6fd..bd83012 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameDiagnosticTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/frames/FrameDiagnosticTests.kt
@@ -7,9 +7,9 @@
     // Ensure the simple case does not report an error
     fun testModel_Accept_Simple() = doTest(
         """
-        import androidx.compose.Model
+        import androidx.compose.<!DEPRECATION!>Model<!>
 
-        @Model
+        @<!DEPRECATION!>Model<!>
         class MyModel {
           var strValue = "default"
         }
@@ -19,9 +19,9 @@
     // Ensure @Model is not used on an open class
     fun testModel_Report_Open() = doTest(
         """
-        import androidx.compose.Model
+        import androidx.compose.<!DEPRECATION!>Model<!>
 
-        @Model
+        @<!DEPRECATION!>Model<!>
         open class <!OPEN_MODEL!>MyModel<!> {
           var strValue = "default"
         }
@@ -31,9 +31,9 @@
     // Ensure @Model is not used on an abstract class
     fun testModel_Report_Abstract() = doTest(
         """
-        import androidx.compose.Model
+        import androidx.compose.<!DEPRECATION!>Model<!>
 
-        @Model
+        @<!DEPRECATION!>Model<!>
         abstract class <!OPEN_MODEL!>MyModel<!> {
           var strValue = "default"
         }
@@ -43,11 +43,11 @@
     // Ensure @Model supports inheriting from a non-model class
     fun testModel_Report_Inheritance() = doTest(
         """
-        import androidx.compose.Model
+        import androidx.compose.<!DEPRECATION!>Model<!>
 
         open class NonModel { }
 
-        @Model
+        @<!DEPRECATION!>Model<!>
         class MyModel : NonModel() {
           var strValue = "default"
         }
@@ -57,12 +57,12 @@
     // Ensure errors are reported when the class is nested.
     fun testModel_Report_Nested_Inheritance() = doTest(
         """
-        import androidx.compose.Model
+        import androidx.compose.<!DEPRECATION!>Model<!>
 
         open class NonModel { }
 
         class Tests {
-            @Model
+            @<!DEPRECATION!>Model<!>
             open class <!OPEN_MODEL!>MyModel<!> : NonModel() {
               var strValue = "default"
             }
diff --git a/compose/compose-runtime/api/0.1.0-dev12.txt b/compose/compose-runtime/api/0.1.0-dev12.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/0.1.0-dev12.txt
+++ b/compose/compose-runtime/api/0.1.0-dev12.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/api/current.txt b/compose/compose-runtime/api/current.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/current.txt
+++ b/compose/compose-runtime/api/current.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev12.txt b/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev12.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev12.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/api/public_plus_experimental_current.txt b/compose/compose-runtime/api/public_plus_experimental_current.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/public_plus_experimental_current.txt
+++ b/compose/compose-runtime/api/public_plus_experimental_current.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/api/restricted_0.1.0-dev12.txt b/compose/compose-runtime/api/restricted_0.1.0-dev12.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/restricted_0.1.0-dev12.txt
+++ b/compose/compose-runtime/api/restricted_0.1.0-dev12.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/api/restricted_current.txt b/compose/compose-runtime/api/restricted_current.txt
index 4565a1e..f418b7f 100644
--- a/compose/compose-runtime/api/restricted_current.txt
+++ b/compose/compose-runtime/api/restricted_current.txt
@@ -227,7 +227,7 @@
     method public static String? keySourceInfoOf(Object key);
   }
 
-  @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
+  @Deprecated @androidx.compose.StableMarker @kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.CLASS) public @interface Model {
   }
 
   @androidx.compose.Stable public interface MutableState<T> extends androidx.compose.State<T> {
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
index 983800a9..0e32118 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmark.kt
@@ -17,9 +17,11 @@
 package androidx.compose.benchmark
 
 import androidx.compose.Composable
-import androidx.compose.Model
 import androidx.compose.Observe
 import androidx.compose.benchmark.realworld4.RealWorld4_FancyWidget_000
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
 import androidx.test.annotation.UiThreadTest
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
@@ -163,8 +165,8 @@
 private val yellowModifier = Modifier.fillMaxSize() + yellowBackground
 private val defaultModifier = yellowModifier
 
-@Model
-class ColorModel(private var color: Color = Color.Black) {
+class ColorModel(color: Color = Color.Black) {
+    private var color: Color by mutableStateOf(color)
     fun toggle() {
         color = if (color == Color.Black) Color.Red else Color.Black
     }
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/SiblingBenchmark.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/SiblingBenchmark.kt
index b7e9c71..f269745 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/SiblingBenchmark.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/SiblingBenchmark.kt
@@ -16,12 +16,12 @@
 
 package androidx.compose.benchmark
 
-import androidx.compose.Model
 import androidx.compose.benchmark.siblings.IdentityType
 import androidx.compose.benchmark.siblings.Item
 import androidx.compose.benchmark.siblings.ReorderType
 import androidx.compose.benchmark.siblings.SiblingManagement
 import androidx.compose.benchmark.siblings.update
+import androidx.compose.mutableStateOf
 import androidx.test.annotation.UiThreadTest
 import androidx.test.filters.LargeTest
 import androidx.test.rule.ActivityTestRule
@@ -83,7 +83,7 @@
     @Test
     fun runBenchmark() {
         activityRule.runUiRunnable {
-            val items = ValueHolder((0..count).map { Item(it) })
+            val items = mutableStateOf((0..count).map { Item(it) })
             val random = Random(0)
             measureRecompose {
                 compose {
@@ -105,5 +105,3 @@
         }
     })
 }
-
-@Model private class ValueHolder<T>(var value: T)
\ No newline at end of file
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
index 1f58e03..f9cf4d6 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/dbmonster/DbMonster.kt
@@ -17,7 +17,9 @@
 package androidx.compose.benchmark.dbmonster
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
 import androidx.ui.core.Modifier
 import androidx.ui.foundation.Text
 import androidx.ui.layout.Column
@@ -36,11 +38,13 @@
 
 private const val MAX_ELAPSED = 15.0
 
-@Model
-class Query(var query: String, var elapsed: Double)
+class Query(query: String, elapsed: Double) {
+    var query by mutableStateOf(query)
+    var elapsed by mutableStateOf(elapsed)
+}
 
-@Model
-class Database(var name: String, random: Random) {
+class Database(name: String, random: Random) {
+    var name: String by mutableStateOf(name)
     private val myRandom = random
     var queries: List<Query> = (1..10).map {
         Query(randomQuery(random), random.nextDouble() * MAX_ELAPSED)
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_DataModels.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_DataModels.kt
index ee6f3a5..d00aadb 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_DataModels.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_DataModels.kt
@@ -21,161 +21,168 @@
  * large scale (eg. gmail-sized application).
  */
 
-import androidx.compose.Model
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
 import androidx.ui.graphics.Color
 
-@Model
 class RealWorld4_DataModel_09() {
-    var f0: Color =
+    var f0: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f1: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f2: RealWorld4_DataModel_10 = RealWorld4_DataModel_10()
-    var f3: Boolean = random.nextBoolean()
-    var f4: Color =
+    )
+    var f1: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f2: RealWorld4_DataModel_10 by mutableStateOf(RealWorld4_DataModel_10())
+    var f3: Boolean by mutableStateOf(random.nextBoolean())
+    var f4: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f5: RealWorld4_DataModel_10 = RealWorld4_DataModel_10()
+    )
+    var f5: RealWorld4_DataModel_10 by mutableStateOf(RealWorld4_DataModel_10())
 }
 
-@Model
 class RealWorld4_DataModel_06() {
-    var f0: Boolean = random.nextBoolean()
-    var f1: Int = random.nextInt()
-    var f2: Boolean = random.nextBoolean()
-    var f3: Color =
+    var f0: Boolean by mutableStateOf(random.nextBoolean())
+    var f1: Int by mutableStateOf(random.nextInt())
+    var f2: Boolean by mutableStateOf(random.nextBoolean())
+    var f3: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f4: Color =
+    )
+    var f4: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f5: Int = random.nextInt()
-    var f6: Int = random.nextInt()
-    var f7: Color =
+    )
+    var f5: Int by mutableStateOf(random.nextInt())
+    var f6: Int by mutableStateOf(random.nextInt())
+    var f7: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f8: Color =
+    )
+    var f8: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f9: Int = random.nextInt()
-    var f10: RealWorld4_DataModel_07 = RealWorld4_DataModel_07()
-    var f11: RealWorld4_DataModel_07 = RealWorld4_DataModel_07()
+    )
+    var f9: Int by mutableStateOf(random.nextInt())
+    var f10: RealWorld4_DataModel_07 by mutableStateOf(RealWorld4_DataModel_07())
+    var f11: RealWorld4_DataModel_07 by mutableStateOf(RealWorld4_DataModel_07())
 }
 
-@Model
 class RealWorld4_DataModel_08() {
-    var f0: RealWorld4_DataModel_09 = RealWorld4_DataModel_09()
-    var f1: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f2: Color =
+    var f0: RealWorld4_DataModel_09 by mutableStateOf(RealWorld4_DataModel_09())
+    var f1: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f2: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f3: Int = random.nextInt()
-    var f4: RealWorld4_DataModel_09 = RealWorld4_DataModel_09()
-    var f5: String = smallRange().map { createSomeText() }.joinToString("\n")
+    )
+    var f3: Int by mutableStateOf(random.nextInt())
+    var f4: RealWorld4_DataModel_09 by mutableStateOf(RealWorld4_DataModel_09())
+    var f5: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
 }
 
-@Model
 class RealWorld4_DataModel_10() {
-    var f0: Boolean = random.nextBoolean()
-    var f1: Int = random.nextInt()
-    var f2: Boolean = random.nextBoolean()
-    var f3: Boolean = random.nextBoolean()
+    var f0: Boolean by mutableStateOf(random.nextBoolean())
+    var f1: Int by mutableStateOf(random.nextInt())
+    var f2: Boolean by mutableStateOf(random.nextBoolean())
+    var f3: Boolean by mutableStateOf(random.nextBoolean())
 }
 
-@Model
 class RealWorld4_DataModel_07() {
-    var f0: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f1: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f2: Int = random.nextInt()
-    var f3: Int = random.nextInt()
-    var f4: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f5: RealWorld4_DataModel_08 = RealWorld4_DataModel_08()
-    var f6: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f7: RealWorld4_DataModel_08 = RealWorld4_DataModel_08()
+    var f0: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f1: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f2: Int by mutableStateOf(random.nextInt())
+    var f3: Int by mutableStateOf(random.nextInt())
+    var f4: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f5: RealWorld4_DataModel_08 by mutableStateOf(RealWorld4_DataModel_08())
+    var f6: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f7: RealWorld4_DataModel_08 by mutableStateOf(RealWorld4_DataModel_08())
 }
 
-@Model
 class RealWorld4_DataModel_05() {
-    var f0: RealWorld4_DataModel_06 = RealWorld4_DataModel_06()
-    var f1: Color =
+    var f0: RealWorld4_DataModel_06 by mutableStateOf(RealWorld4_DataModel_06())
+    var f1: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f2: Color =
+    )
+    var f2: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f3: Color =
+    )
+    var f3: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f4: Boolean = random.nextBoolean()
-    var f5: Boolean = random.nextBoolean()
-    var f6: RealWorld4_DataModel_06 = RealWorld4_DataModel_06()
-    var f7: String = smallRange().map { createSomeText() }.joinToString("\n")
+    )
+    var f4: Boolean by mutableStateOf(random.nextBoolean())
+    var f5: Boolean by mutableStateOf(random.nextBoolean())
+    var f6: RealWorld4_DataModel_06 by mutableStateOf(RealWorld4_DataModel_06())
+    var f7: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
 }
 
-@Model
 class RealWorld4_DataModel_00() {
-    var f0: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f1: Int = random.nextInt()
-    var f2: RealWorld4_DataModel_01 = RealWorld4_DataModel_01()
-    var f3: RealWorld4_DataModel_01 = RealWorld4_DataModel_01()
-    var f4: Int = random.nextInt()
-    var f5: Color =
+    var f0: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f1: Int by mutableStateOf(random.nextInt())
+    var f2: RealWorld4_DataModel_01 by mutableStateOf(RealWorld4_DataModel_01())
+    var f3: RealWorld4_DataModel_01 by mutableStateOf(RealWorld4_DataModel_01())
+    var f4: Int by mutableStateOf(random.nextInt())
+    var f5: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f6: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f7: Int = random.nextInt()
-    var f8: Int = random.nextInt()
+    )
+    var f6: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f7: Int by mutableStateOf(random.nextInt())
+    var f8: Int by mutableStateOf(random.nextInt())
 }
 
-@Model
 class RealWorld4_DataModel_02() {
-    var f0: Int = random.nextInt()
-    var f1: RealWorld4_DataModel_03 = RealWorld4_DataModel_03()
-    var f2: Boolean = random.nextBoolean()
-    var f3: Color =
+    var f0: Int by mutableStateOf(random.nextInt())
+    var f1: RealWorld4_DataModel_03 by mutableStateOf(RealWorld4_DataModel_03())
+    var f2: Boolean by mutableStateOf(random.nextBoolean())
+    var f3: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f4: Int = random.nextInt()
-    var f5: Int = random.nextInt()
-    var f6: RealWorld4_DataModel_03 = RealWorld4_DataModel_03()
-    var f7: Int = random.nextInt()
-    var f8: Int = random.nextInt()
-    var f9: Color =
+    )
+    var f4: Int by mutableStateOf(random.nextInt())
+    var f5: Int by mutableStateOf(random.nextInt())
+    var f6: RealWorld4_DataModel_03 by mutableStateOf(RealWorld4_DataModel_03())
+    var f7: Int by mutableStateOf(random.nextInt())
+    var f8: Int by mutableStateOf(random.nextInt())
+    var f9: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
+    )
 }
 
-@Model
 class RealWorld4_DataModel_04() {
-    var f0: RealWorld4_DataModel_05 = RealWorld4_DataModel_05()
-    var f1_modified: Boolean = random.nextBoolean()
-    var f2: RealWorld4_DataModel_05 = RealWorld4_DataModel_05()
-    var f3: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f4: Boolean = random.nextBoolean()
-    var f5: Boolean = random.nextBoolean()
-    var f6: Boolean = random.nextBoolean()
-    var f7: Boolean = random.nextBoolean()
-    var f8: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f9: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f10: String = smallRange().map { createSomeText() }.joinToString("\n")
+    var f0: RealWorld4_DataModel_05 by mutableStateOf(RealWorld4_DataModel_05())
+    var f1_modified: Boolean by mutableStateOf(random.nextBoolean())
+    var f2: RealWorld4_DataModel_05 by mutableStateOf(RealWorld4_DataModel_05())
+    var f3: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f4: Boolean by mutableStateOf(random.nextBoolean())
+    var f5: Boolean by mutableStateOf(random.nextBoolean())
+    var f6: Boolean by mutableStateOf(random.nextBoolean())
+    var f7: Boolean by mutableStateOf(random.nextBoolean())
+    var f8: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f9: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f10: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
 }
 
-@Model
 class RealWorld4_DataModel_01() {
-    var f0: RealWorld4_DataModel_02 = RealWorld4_DataModel_02()
-    var f1: Int = random.nextInt()
-    var f2: Color =
+    var f0: RealWorld4_DataModel_02 by mutableStateOf(RealWorld4_DataModel_02())
+    var f1: Int by mutableStateOf(random.nextInt())
+    var f2: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f3: Boolean = random.nextBoolean()
-    var f4: Boolean = random.nextBoolean()
-    var f5: Int = random.nextInt()
-    var f6: Boolean = random.nextBoolean()
-    var f7: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f8: String = smallRange().map { createSomeText() }.joinToString("\n")
-    var f9: Boolean = random.nextBoolean()
-    var f10: Int = random.nextInt()
-    var f11: Int = random.nextInt()
-    var f12: Boolean = random.nextBoolean()
-    var f13: Boolean = random.nextBoolean()
-    var f14: Int = random.nextInt()
-    var f15: RealWorld4_DataModel_02 = RealWorld4_DataModel_02()
+    )
+    var f3: Boolean by mutableStateOf(random.nextBoolean())
+    var f4: Boolean by mutableStateOf(random.nextBoolean())
+    var f5: Int by mutableStateOf(random.nextInt())
+    var f6: Boolean by mutableStateOf(random.nextBoolean())
+    var f7: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f8: String by mutableStateOf(smallRange().map { createSomeText() }.joinToString("\n"))
+    var f9: Boolean by mutableStateOf(random.nextBoolean())
+    var f10: Int by mutableStateOf(random.nextInt())
+    var f11: Int by mutableStateOf(random.nextInt())
+    var f12: Boolean by mutableStateOf(random.nextBoolean())
+    var f13: Boolean by mutableStateOf(random.nextBoolean())
+    var f14: Int by mutableStateOf(random.nextInt())
+    var f15: RealWorld4_DataModel_02 by mutableStateOf(RealWorld4_DataModel_02())
 }
 
-@Model
 class RealWorld4_DataModel_03() {
-    var f0: Color =
+    var f0: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f1: RealWorld4_DataModel_04 = RealWorld4_DataModel_04()
-    var f2: Int = random.nextInt()
-    var f3: Color =
+    )
+    var f1: RealWorld4_DataModel_04 by mutableStateOf(RealWorld4_DataModel_04())
+    var f2: Int by mutableStateOf(random.nextInt())
+    var f3: Color by mutableStateOf(
         Color(red = random.nextInt(255), green = random.nextInt(255), blue = random.nextInt(255))
-    var f4: Boolean = random.nextBoolean()
-    var f5: RealWorld4_DataModel_04 = RealWorld4_DataModel_04()
+    )
+    var f4: Boolean by mutableStateOf(random.nextBoolean())
+    var f5: RealWorld4_DataModel_04 by mutableStateOf(RealWorld4_DataModel_04())
 }
diff --git a/compose/compose-runtime/samples/src/main/java/androidx/compose/samples/ModelSamples.kt b/compose/compose-runtime/samples/src/main/java/androidx/compose/samples/ModelSamples.kt
index 6f2599f..23fda24 100644
--- a/compose/compose-runtime/samples/src/main/java/androidx/compose/samples/ModelSamples.kt
+++ b/compose/compose-runtime/samples/src/main/java/androidx/compose/samples/ModelSamples.kt
@@ -18,8 +18,9 @@
 
 import androidx.annotation.Sampled
 import androidx.compose.Composable
-import androidx.compose.Model
-import androidx.compose.remember
+import androidx.compose.getValue
+import androidx.compose.setValue
+import androidx.compose.state
 import androidx.ui.foundation.TextField
 import androidx.ui.foundation.Text
 import androidx.ui.material.Button
@@ -27,28 +28,23 @@
 
 @Composable
 @Sampled
-fun modelSample() {
-    @Model
-    class LoginState(var username: TextFieldValue, var password: TextFieldValue) {
-        fun login() = Api.login(username.text, password.text)
-    }
-
+fun stateSample() {
     @Composable
     fun LoginScreen() {
-        val model = remember { LoginState(
-            TextFieldValue("user"),
-            TextFieldValue("pass")
-        ) }
+        var username by state { TextFieldValue("user") }
+        var password by state { TextFieldValue("pass") }
+
+        fun login() = Api.login(username.text, password.text)
 
         TextField(
-            value = model.username,
-             model.username = it }
+            value = username,
+             username = it }
         )
         TextField(
-            value = model.password,
-             model.password = it }
+            value = password,
+             password = it }
         )
-        Button( model.login() }) {
+        Button( login() }) {
             Text("Login")
         }
     }
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
index ffe80b0..34de9e8 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
@@ -153,7 +153,7 @@
      * Records that [value], or one of its fields, read while composing and its values were
      * used during composition.
      *
-     * This is the underlying mechanism used by [Model] objects to allow composition to observe
+     * This is the underlying mechanism used by [State] objects to allow composition to observe
      * changes made to model objects.
      */
     internal fun recordRead(value: Any) = readObserver(value)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Model.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Model.kt
index 0c167b3..91e2463 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Model.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Model.kt
@@ -26,19 +26,16 @@
  *
  * [Model] also adds an MVCC transaction system to ensure data consistency across threads.
  *
- * Consider the following example:
- *
- * @sample androidx.compose.samples.modelSample
- *
- * In this example, `LoginScreen` is recomposed every time the username and password of the
- * model updates, keeping the UI synchronized with the model. There is no need to call
- * [androidx.compose.Recompose] manually.
- *
  * @see FrameManager
  * @see Observe
+ * @see state
+ * @see mutableStateOf
+ * @see State
+ * @see MutableState
  */
 @MustBeDocumented
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.BINARY)
 @StableMarker
+@Deprecated("Use mutableStateOf and associated State<T> variants")
 annotation class Model
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/MutableState.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/MutableState.kt
index bd0cc63..68e41a1 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/MutableState.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/MutableState.kt
@@ -29,14 +29,19 @@
  * A composable used to introduce a state value of type [T] into a composition.
  *
  * This is useful when you have a value that you would like to locally mutate and use in the context of a composition. Since
- * the returned [MutableState] instance implements [Model], changes to the [MutableState.value] property will be automatically tracked in
- * composition and schedule a recompose.
+ * the returned [MutableState] instance implements [Framed], changes to the [MutableState.value]
+ * property will be automatically tracked in composition and schedule a recompose.
  *
  * The [MutableState] class can be used several different ways. For example, the most basic way is to store the returned state
  * value into a local immutable variable, and then set the [MutableState.value] property on it.
  *
  * @sample androidx.compose.samples.SimpleStateSample
  *
+ * @sample androidx.compose.samples.stateSample
+ *
+ * In this example, `LoginScreen` is recomposed every time the username and password of the
+ * model updates, keeping the UI synchronized with the state.
+ *
  * Additionally, you can destructure the [MutableState] object into a value and a "setter" function.
  *
  * @sample androidx.compose.samples.DestructuredStateSample
@@ -49,7 +54,7 @@
  * [MutableState.value] is written to. If this returns true, then no recomposition will be
  * scheduled. See [ReferentiallyEqual] and [StructurallyEqual] for simple implementations.
  * @param init A factory function to create the initial value of this state
- * @return An [Model] instance of [MutableState] that wraps the value.
+ * @return An instance of [MutableState] that wraps the value.
  *
  * @see [stateFor]
  * @see [remember]
@@ -66,12 +71,13 @@
  * This is useful when you have a value that you would like to locally mutate and use in the context of a composition, and its
  * value is scoped to another value and you want it to be reset every time the other value changes.
  *
- * The returned [MutableState] instance implements [Model] so that changes to the [MutableState.value] property will be automatically tracked in
- * composition and schedule a recompose.
+ * The returned [MutableState] instance implements [Framed] so that changes to the
+ * [MutableState.value] property will be automatically tracked in composition and schedule a
+ * recompose.
  *
  * @param v1 An input value that, when changed, will cause the state to reset and [init] to be rerun
  * @param init A factory function to create the initial value of this state
- * @return An [Model] instance of [MutableState] that wraps the value.
+ * @return An instance of [MutableState] that wraps the value.
  *
  * @sample androidx.compose.samples.observeUserSample
  *
@@ -88,13 +94,14 @@
  * This is useful when you have a value that you would like to locally mutate and use in the context of a composition, and its
  * value is scoped to another value and you want it to be reset every time the other value changes.
  *
- * The returned [MutableState] instance implements [Model] so that changes to the [MutableState.value] property will be automatically tracked in
- * composition and schedule a recompose.
+ * The returned [MutableState] instance implements [Framed] such that changes to the
+ * [MutableState.value] property will be automatically tracked in composition and schedule a
+ * recompose.
  *
  * @param v1 An input value that, when changed, will cause the state to reset and [init] to be rerun
  * @param v2 An input value that, when changed, will cause the state to reset and [init] to be rerun
  * @param init A factory function to create the initial value of this state
- * @return An [Model] instance of [MutableState] that wraps the value.
+ * @return An instance of [MutableState] that wraps the value.
  *
  * @see [state]
  * @see [remember]
@@ -112,12 +119,13 @@
  * This is useful when you have a value that you would like to locally mutate and use in the context of a composition, and its
  * value is scoped to another value and you want it to be reset every time the other value changes.
  *
- * The returned [MutableState] instance implements [Model] so that changes to the [MutableState.value] property will be automatically tracked in
- * composition and schedule a recompose.
+ * The returned [MutableState] instance implements [Framed] so that changes to the
+ * [MutableState.value] property will be automatically tracked in composition and schedule a
+ * recompose.
  *
  * @param inputs A set of inputs such that, when any of them have changed, will cause the state to reset and [init] to be rerun
  * @param init A factory function to create the initial value of this state
- * @return An [Model] instance of [MutableState] that wraps the value.
+ * @return An instance of [MutableState] that wraps the value.
  *
  * @see [state]
  * @see [remember]
@@ -129,15 +137,25 @@
 /**
  * Return a new [MutableState] initialized with the passed in [value]
  *
+ * The MutableState class is a single value holder whose reads and writes are observed by
+ * Compose. Additionally, writes to it are transacted as part of the [Framed] transaction system.
+ * During composition, you will likely want to use the `state` and `stateFor` composables instead
+ * of this factory function.
+ *
  * @param value the initial value for the [MutableState]
  * @param areEquivalent a callback to compare the previous and new instance of [value] when
  * it is written to. If this returns true, then no recomposition will be scheduled. See
  * [ReferentiallyEqual] and [StructurallyEqual] for simple implementations.
+ *
+ * @see state
+ * @see stateFor
+ * @see State
+ * @see MutableState
  */
 fun <T> mutableStateOf(
     value: T,
     areEquivalent: (old: T, new: T) -> Boolean = ReferentiallyEqual
-): MutableState<T> = ModelMutableState(value, areEquivalent)
+): MutableState<T> = FramedMutableState(value, areEquivalent)
 
 /**
  * Simple comparison callback using referential `===` equality
@@ -208,18 +226,20 @@
 }
 
 /**
- * The State class is an @Model class meant to wrap around a single value. It is used in the
+ * The ModelMutableState class is a single value holder whose reads and writes are observed by
+ * Compose.
+ * Additionally, writes to it are transacted as part of the [Framed] transaction system.
  * `state` and `stateFor` composables.
  *
  * @property value the wrapped value
  * @property areEquivalent function used for comparing old and new [value]s to determine whether
  * to trigger a recomposition or not.
  *
- * @see [Model]
  * @see [state]
  * @see [stateFor]
+ * @see [mutableStateOf]
  */
-private class ModelMutableState<T>(
+private class FramedMutableState<T>(
     value: T,
     val areEquivalent: (old: T, new: T) -> Boolean
 ) : Framed, MutableState<T> {
@@ -229,9 +249,6 @@
     override var value: T
         get() = next.readable(this).value
         set(value) = next.withCurrent {
-            // This intentionally deviates from the typical behavior of @Model. When this is
-            // converted to an IR module, this behavior should be preserved with a custom setter
-            // on the property in the @Model class.
             if (!areEquivalent(it.value, value)) {
                 next.writable(this).value = value
             }
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Observe.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Observe.kt
index 7f90b5d..78284b2 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Observe.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Observe.kt
@@ -18,14 +18,14 @@
 
 /**
  * This component creates a scope which will be the root of recomposition for any reads or writes to
- * [Model] classes that happen inside of it. This can be used to improve performance in situations
- * where you know that a specific [Model] object will need to change at high frequencies, and you
+ * state instances that happen inside of it. This can be used to improve performance in situations
+ * where you know that a specific state object will need to change at high frequencies, and you
  * want to reduce the burden of recomposition.  It is recommended that you not introduce [Observe]
  * into the composition until it is clear that is necessary to improve performance.
  *
  * @param body The composable content to observe
  *
- * @see Model
+ * @see state
  * @see invalidate
  * @see Recompose
  */
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recompose.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recompose.kt
index 3842c9e..185f5d6 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recompose.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Recompose.kt
@@ -21,7 +21,7 @@
  * invoked, will cause its children to recompose. This is useful if you are updating local state
  * and need to cause a recomposition manually.
  *
- * In most cases we recommend using [Model] classes or [state] with immutable types in order to
+ * In most cases we recommend using [state] with immutable types in order to
  * maintain local state inside of composables. For cases where this is impractical, Recompose can
  * help you.
  *
@@ -29,9 +29,9 @@
  *
  * @sample androidx.compose.samples.recomposeSample
  *
- * Note: The above example can be done without [Recompose] by annotating `LoginState` with [Model].
+ * Note: The above example can be done without [Recompose] by using [state].
  *
- * @see Model
+ * @see state
  * @see Observe
  * @see invalidate
  */
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/StableMarker.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/StableMarker.kt
index 5bfb4dd..56960ef 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/StableMarker.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/StableMarker.kt
@@ -28,13 +28,8 @@
  * change. The [Immutable] annotation is provided to mark immutable types as stable.
  *
  * An object whose public properties do not change but is not immutable (for example, it has
- * private mutable state or uses property delegation to a [Model] object, such as a
- * [MutableState] instance, but is otherwise immutable), should use the [Stable] annotation.
- *
- * [Model] types are mutable but obeys the above assumptions because any change to a public
- * property of a [Model] type notifies composition when the change is committed; therefore the
- * [Model] annotation is annotated [StableMarker] and all type annotated with [Model] are assumed
- * to be stable.
+ * private mutable state or uses property delegation to a [MutableState] object, but is otherwise
+ * immutable), should use the [Stable] annotation.
  *
  * Mutable object that do not notify composition when they changed should not be marked as stable.
  *
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ModelObserverBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ModelObserverBenchmark.kt
index ef6b479..d1d3ef2 100644
--- a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ModelObserverBenchmark.kt
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/ModelObserverBenchmark.kt
@@ -19,10 +19,10 @@
 import android.os.Handler
 import android.os.Looper
 import androidx.compose.FrameManager
-import androidx.compose.Model
 import androidx.compose.frames.commit
 import androidx.compose.frames.inFrame
 import androidx.compose.frames.open
+import androidx.compose.mutableStateOf
 import androidx.test.filters.LargeTest
 import androidx.ui.benchmark.ComposeBenchmarkRule
 import androidx.ui.core.ModelObserver
@@ -61,7 +61,7 @@
     val rule = ComposeBenchmarkRule(enableTransitions = false)
 
     lateinit var modelObserver: ModelObserver
-    val models = List(numberOfModels) { SimpleModel() }
+    val models = List(numberOfModels) { mutableStateOf(0) }
     val nodes = List(numberOfNodes) { it }
     lateinit var random: Random
     val numObservations = numberOfModels / 10
@@ -165,6 +165,3 @@
         }
     }
 }
-
-@Model
-class SimpleModel(var value: Int = 0)
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt
index d0e9888..29cd29f 100644
--- a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/benchmark/test/RadioGroupBenchmark.kt
@@ -17,7 +17,7 @@
 package androidx.ui.benchmark.test
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import androidx.ui.benchmark.ComposeBenchmarkRule
@@ -91,17 +91,14 @@
     }
 }
 
-@Model
-internal class RadioGroupSelectedState<T>(var selected: T)
-
 internal class RadioGroupTestCase : ComposeTestCase, ToggleableTestCase {
 
     private val radiosCount = 10
     private val options = (0 until radiosCount).toList()
-    private val select = RadioGroupSelectedState(0)
+    private val select = mutableStateOf(0)
 
     override fun toggleState() {
-        select.selected = (select.selected + 1) % radiosCount
+        select.value = (select.value + 1) % radiosCount
     }
 
     @Composable
@@ -112,8 +109,8 @@
                     options.forEach { item ->
                         RadioGroupTextItem(
                             text = item.toString(),
-                            selected = (select.selected == item),
-                             select.selected = item })
+                            selected = (select.value == item),
+                             select.value = item })
                     }
                 }
             }
diff --git a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoColorPalette.kt b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoColorPalette.kt
index 920018e..959d519 100644
--- a/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoColorPalette.kt
+++ b/ui/integration-tests/demos/src/main/java/androidx/ui/demos/DemoColorPalette.kt
@@ -18,20 +18,23 @@
 
 import android.content.SharedPreferences
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
 import androidx.ui.foundation.isSystemInDarkTheme
 import androidx.ui.material.ColorPalette
 import androidx.ui.material.darkColorPalette
 import androidx.ui.material.lightColorPalette
 
 /**
- * Wrapper [Model] class that contains a light and dark [ColorPalette], to allow saving and
+ * Wrapper class that contains a light and dark [ColorPalette], to allow saving and
  * restoring the entire light / dark theme to and from [SharedPreferences].
  */
-@Model
+@Stable
 class DemoColorPalette {
-    var lightColors: ColorPalette = lightColorPalette()
-    var darkColors: ColorPalette = darkColorPalette()
+    var lightColors: ColorPalette by mutableStateOf(lightColorPalette())
+    var darkColors: ColorPalette by mutableStateOf(darkColorPalette())
 
     @Composable
     val colors
diff --git a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnSharedModelTestCase.kt b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnSharedModelTestCase.kt
index 4d54658..7d34bc3 100644
--- a/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnSharedModelTestCase.kt
+++ b/ui/integration-tests/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnSharedModelTestCase.kt
@@ -17,7 +17,7 @@
 package androidx.ui.integration.test.foundation
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.ui.core.Modifier
 import androidx.ui.foundation.Box
 import androidx.ui.unit.dp
@@ -29,9 +29,6 @@
 import androidx.ui.integration.test.ToggleableTestCase
 import androidx.ui.layout.preferredSize
 
-@Model
-private class RectanglesInColumnTestCaseColorModel(var color: Color)
-
 /**
  * Test case that puts the given amount of rectangles into a column layout and makes changes by
  * modifying the color used in the model.
@@ -43,7 +40,7 @@
     private val amountOfRectangles: Int
 ) : ComposeTestCase, ToggleableTestCase {
 
-    private val model = RectanglesInColumnTestCaseColorModel(Color.Black)
+    private val color = mutableStateOf(Color.Black)
 
     @Composable
     override fun emitContent() {
@@ -51,7 +48,7 @@
             Column {
                 repeat(amountOfRectangles) { i ->
                     if (i == 0) {
-                        Box(Modifier.preferredSize(100.dp, 50.dp).drawBackground(model.color))
+                        Box(Modifier.preferredSize(100.dp, 50.dp).drawBackground(color.value))
                     } else {
                         Box(Modifier.preferredSize(100.dp, 50.dp).drawBackground(Color.Green))
                     }
@@ -61,10 +58,10 @@
     }
 
     override fun toggleState() {
-        if (model.color == Color.Magenta) {
-            model.color = Color.Blue
+        if (color.value == Color.Magenta) {
+            color.value = Color.Blue
         } else {
-            model.color = Color.Magenta
+            color.value = Color.Magenta
         }
     }
 }
\ No newline at end of file
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
index 2374e74..0bededb 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
@@ -39,15 +39,18 @@
 import androidx.ui.androidview.adapters.setOnClick
 import androidx.ui.androidview.adapters.setOnTextChanged
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
 import androidx.compose.state
 import androidx.ui.androidview.WebComponent
 import androidx.ui.androidview.WebContext
 import androidx.ui.core.setViewContent
 
-@Model
+@Stable
 class WebParams {
-    var url: String = "https://www.google.com"
+    var url: String by mutableStateOf("https://www.google.com")
 }
 
 open class WebComponentActivity : ComponentActivity() {
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
index 6e0f9b0..6a47e02 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/AnimatedValueEffects.kt
@@ -24,6 +24,7 @@
 import androidx.animation.Spring
 import androidx.animation.TwoWayConverter
 import androidx.compose.Composable
+import androidx.compose.Stable
 import androidx.compose.StructurallyEqual
 import androidx.compose.getValue
 import androidx.compose.mutableStateOf
@@ -101,6 +102,7 @@
  *                      [AnimationVector] type
  * @param clock The animation clock that will be used to drive the animation
  */
+@Stable
 class AnimatedValueModel<T, V : AnimationVector>(
     initialValue: T,
     typeConverter: TwoWayConverter<T, V>,
@@ -117,6 +119,7 @@
  * @param initialValue The overridden value field that can only be mutated by animation
  * @param clock The animation clock that will be used to drive the animation
  */
+@Stable
 class AnimatedFloatModel(
     initialValue: Float,
     clock: AnimationClockObservable,
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
index 7645fde..0af984e 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
@@ -24,9 +24,12 @@
 import androidx.animation.TransitionState
 import androidx.animation.createAnimation
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
 import androidx.compose.onPreCommit
 import androidx.compose.remember
+import androidx.compose.setValue
 import androidx.ui.core.AnimationClockAmbient
 
 /**
@@ -101,14 +104,14 @@
 var transitionsEnabled = true
 
 // TODO(Doris): Use Clock idea instead of TransitionModel with pulse
-@Model
+@Stable
 private class TransitionModel<T>(
     transitionDef: TransitionDefinition<T>,
     initState: T,
     clock: AnimationClockObservable
 ) : TransitionState {
 
-    private var animationPulse = 0L
+    private var animationPulse by mutableStateOf(0L)
     internal val anim: TransitionAnimation<T> =
         transitionDef.createAnimation(clock, initState).apply {
             >
@@ -117,7 +120,7 @@
         }
 
     override fun <T, V : AnimationVector> get(propKey: PropKey<T, V>): T {
-        // we need to access the animationPulse so Compose will record this @Model values usage.
+        // we need to access the animationPulse so Compose will record this state values usage.
         @Suppress("UNUSED_VARIABLE")
         val pulse = animationPulse
         return anim[propKey]
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index 49c72ad..156df58 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -29,10 +29,13 @@
 import androidx.annotation.RequiresApi
 import androidx.compose.Composable
 import androidx.compose.FrameManager
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.State
 import androidx.compose.emptyContent
+import androidx.compose.getValue
 import androidx.compose.mutableStateOf
 import androidx.compose.remember
+import androidx.compose.setValue
 import androidx.compose.state
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
@@ -212,13 +215,13 @@
         val white = Color(0xFFFFFFFF)
         val blue = Color(0xFF000080)
         val model = SquareModel(outerColor = blue, innerColor = white)
-        val offset = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         composeMovingSquaresWithRepaintBoundary(model, offset)
         validateSquareColors(outerColor = blue, innerColor = white, size = 10)
 
         positionLatch = CountDownLatch(1)
         activityTestRule.runOnUiThreadIR {
-            offset.offset = 20.ipx
+            offset.value = 20.ipx
         }
 
         assertTrue(positionLatch!!.await(1, TimeUnit.SECONDS))
@@ -233,7 +236,7 @@
         val white = Color(0xFFFFFFFF)
         val blue = Color(0xFF000080)
         val model = SquareModel(outerColor = blue, innerColor = white)
-        val offset = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         composeMovingSquares(model, offset)
         validateSquareColors(outerColor = blue, innerColor = white, size = 10)
 
@@ -247,7 +250,7 @@
                     drawLatch.countDown()
                 }
             })
-            offset.offset = 20.ipx
+            offset.value = 20.ipx
         }
 
         validateSquareColors(outerColor = blue, innerColor = white, offset = 10, size = 10)
@@ -576,7 +579,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun testRelayoutOnNewChild() {
-        val drawChild = DoDraw()
+        val drawChild = mutableStateOf(false)
 
         val outerColor = Color(0xFF000080)
         val innerColor = Color(0xFFFFFFFF)
@@ -608,7 +611,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun moveRootLayoutRedrawsLeafRepaintBoundary() {
-        val offset = OffsetModel(0.ipx)
+        val offset = mutableStateOf(0.ipx)
         drawLatch = CountDownLatch(2)
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
@@ -626,7 +629,7 @@
                 ) { measurables, constraints, _ ->
                     layout(width = 20.ipx, height = 20.ipx) {
                         measurables.first().measure(constraints)
-                            .place(offset.offset, offset.offset)
+                            .place(offset.value, offset.value)
                     }
                 }
             }
@@ -639,7 +642,7 @@
         }
 
         drawLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { offset.offset = 10.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 10.ipx }
 
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
         activityTestRule.waitAndScreenShot().apply {
@@ -652,7 +655,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun testRedrawOnRemovedChild() {
-        val drawChild = DoDraw(true)
+        val drawChild = mutableStateOf(true)
 
         val outerColor = Color(0xFF000080)
         val innerColor = Color(0xFFFFFFFF)
@@ -692,7 +695,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun testRelayoutOnRemovedChild() {
-        val drawChild = DoDraw(true)
+        val drawChild = mutableStateOf(true)
 
         val outerColor = Color(0xFF000080)
         val innerColor = Color(0xFFFFFFFF)
@@ -1020,7 +1023,7 @@
     fun testAlignmentLines_recomposeCorrectly() {
         val TestLine = VerticalAlignmentLine(::min)
         var layoutLatch = CountDownLatch(1)
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         var measure = 0
         var layout = 0
         var linePosition: IntPx? = null
@@ -1028,7 +1031,7 @@
             activity.setContent {
                 val child = @Composable {
                     Layout(children = {}) { _, _, _ ->
-                        layout(0.ipx, 0.ipx, mapOf(TestLine to model.offset)) {}
+                        layout(0.ipx, 0.ipx, mapOf(TestLine to offset.value)) {}
                     }
                 }
                 Layout(child) { measurables, constraints, _ ->
@@ -1049,7 +1052,7 @@
 
         layoutLatch = CountDownLatch(1)
         activityTestRule.runOnUiThreadIR {
-            model.offset = 20.ipx
+            offset.value = 20.ipx
         }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(2, measure)
@@ -1061,7 +1064,7 @@
     fun testAlignmentLines_recomposeCorrectly_whenQueriedInLayout() {
         val TestLine = VerticalAlignmentLine(::min)
         var layoutLatch = CountDownLatch(1)
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         var measure = 0
         var layout = 0
         var linePosition: IntPx? = null
@@ -1072,7 +1075,7 @@
                         layout(
                             0.ipx,
                             0.ipx,
-                            mapOf(TestLine to model.offset)
+                            mapOf(TestLine to offset.value)
                         ) {}
                     }
                 }
@@ -1093,7 +1096,7 @@
         assertEquals(10.ipx, linePosition)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 20.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 20.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(2, measure)
         assertEquals(2, layout)
@@ -1104,7 +1107,7 @@
     fun testAlignmentLines_recomposeCorrectly_whenMeasuredAndQueriedInLayout() {
         val TestLine = VerticalAlignmentLine(::min)
         var layoutLatch = CountDownLatch(1)
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         var measure = 0
         var layout = 0
         var linePosition: IntPx? = null
@@ -1112,7 +1115,7 @@
             activity.setContent {
                 val child = @Composable {
                     Layout(children = {}) { _, _, _ ->
-                        layout(0.ipx, 0.ipx, mapOf(TestLine to model.offset)) { }
+                        layout(0.ipx, 0.ipx, mapOf(TestLine to offset.value)) { }
                     }
                 }
                 Layout(child) { measurables, constraints, _ ->
@@ -1132,7 +1135,7 @@
         assertEquals(10.ipx, linePosition)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 20.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 20.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(1, measure)
         assertEquals(2, layout)
@@ -1142,7 +1145,7 @@
     @Test
     fun testAlignmentLines_onlyComputesAlignmentLinesWhenNeeded() {
         var layoutLatch = CountDownLatch(1)
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         var alignmentLinesCalculations = 0
         val TestLine = VerticalAlignmentLine { _, _ ->
             ++alignmentLinesCalculations
@@ -1151,14 +1154,14 @@
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 val innerChild = @Composable {
-                    model.offset // Artificial remeasure.
+                    offset.value // Artificial remeasure.
                     Layout(children = {}) { _, _, _ ->
                         layout(0.ipx, 0.ipx, mapOf(TestLine to 10.ipx)) { }
                     }
                 }
                 val child = @Composable {
                     Layout({ innerChild(); innerChild() }) { measurables, constraints, _ ->
-                        model.offset // Artificial remeasure.
+                        offset.value // Artificial remeasure.
                         val placeable1 = measurables[0].measure(constraints)
                         val placeable2 = measurables[1].measure(constraints)
                         layout(0.ipx, 0.ipx) {
@@ -1169,7 +1172,7 @@
                 }
                 Layout(child) { measurables, constraints, _ ->
                     val placeable = measurables.first().measure(constraints)
-                    if (model.offset < 15.ipx) {
+                    if (offset.value < 15.ipx) {
                         placeable[TestLine]
                     }
                     layout(0.ipx, 0.ipx) {
@@ -1183,12 +1186,12 @@
         assertEquals(1, alignmentLinesCalculations)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 20.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 20.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(1, alignmentLinesCalculations)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 10.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 10.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(2, alignmentLinesCalculations)
     }
@@ -1233,7 +1236,7 @@
         var innerChildLayouts = 0
         var outerChildMeasures = 0
         var outerChildLayouts = 0
-        val model = OffsetModel(0.ipx)
+        val offset = mutableStateOf(0.ipx)
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 val child = @Composable {
@@ -1248,7 +1251,7 @@
                         val placeable = measurables[0].measure(constraints)
                         layout(0.ipx, 0.ipx) {
                             ++outerChildLayouts
-                            placeable.place(model.offset, 0.ipx)
+                            placeable.place(offset.value, 0.ipx)
                         }
                     }
                 }
@@ -1257,7 +1260,7 @@
                     val width = placeable.width.coerceAtLeast(10.ipx)
                     val height = placeable.height.coerceAtLeast(10.ipx)
                     layout(width, height) {
-                        assertEquals(model.offset + 10.ipx, placeable[TestLine])
+                        assertEquals(offset.value + 10.ipx, placeable[TestLine])
                         placeable.place(0.ipx, 0.ipx)
                         layoutLatch.countDown()
                     }
@@ -1272,7 +1275,7 @@
 
         layoutLatch = CountDownLatch(1)
         activityTestRule.runOnUiThreadIR {
-            model.offset = 10.ipx
+            offset.value = 10.ipx
         }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(1, innerChildMeasures)
@@ -1325,7 +1328,7 @@
         val TestLine = VerticalAlignmentLine(::min)
         var layoutLatch = CountDownLatch(1)
         var childLayouts = 0
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 val child = @Composable {
@@ -1335,20 +1338,20 @@
                             constraints.minHeight,
                             mapOf(TestLine to 10.ipx)
                         ) {
-                            model.offset // To ensure relayout.
+                            offset.value // To ensure relayout.
                             ++childLayouts
                         }
                     }
                 }
                 val inner = @Composable {
                     Layout({
-                        WrapForceRelayout(model) { child() }
+                        WrapForceRelayout(offset) { child() }
                     }) { measurables, constraints, _ ->
                         val placeable = measurables[0].measure(constraints)
                         layout(placeable.width, placeable.height) {
-                            if (model.offset > 15.ipx) assertEquals(10.ipx, placeable[TestLine])
+                            if (offset.value > 15.ipx) assertEquals(10.ipx, placeable[TestLine])
                             placeable.place(0.ipx, 0.ipx)
-                            if (model.offset > 5.ipx) assertEquals(10.ipx, placeable[TestLine])
+                            if (offset.value > 5.ipx) assertEquals(10.ipx, placeable[TestLine])
                         }
                     }
                 }
@@ -1357,7 +1360,7 @@
                     val width = placeable.width.coerceAtLeast(10.ipx)
                     val height = placeable.height.coerceAtLeast(10.ipx)
                     layout(width, height) {
-                        model.offset // To ensure relayout.
+                        offset.value // To ensure relayout.
                         placeable.place(0.ipx, 0.ipx)
                         layoutLatch.countDown()
                     }
@@ -1369,29 +1372,29 @@
         assertEquals(2, childLayouts)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 12.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 12.ipx }
         assertTrue(layoutLatch.await(5, TimeUnit.SECONDS))
         // Just one more layout as the alignment lines were speculatively calculated this time.
         assertEquals(3, childLayouts)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 17.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 17.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         // One layout as the alignment lines are queried before.
         assertEquals(4, childLayouts)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 12.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 12.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         // One layout as the alignment lines are still calculated speculatively.
         assertEquals(5, childLayouts)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 1.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 1.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(6, childLayouts)
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThreadIR { model.offset = 10.ipx }
+        activityTestRule.runOnUiThreadIR { offset.value = 10.ipx }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         // Two layouts again, since alignment lines were not queried during last layout,
         // so we did not calculate them speculatively anymore.
@@ -1551,7 +1554,7 @@
 
     @Test
     fun testLayoutBeforeDraw_forRecomposingNodesNotAffectingRootSize() {
-        val model = OffsetModel(0.ipx)
+        val offset = mutableStateOf(0.ipx)
         var latch = CountDownLatch(1)
         var laidOut = false
         activityTestRule.runOnUiThreadIR {
@@ -1567,7 +1570,7 @@
                 }
                 val recomposingChild = @Composable { children: @Composable (IntPx) -> Unit ->
                     // This simulates a child that recomposes, for example due to a transition.
-                    children(model.offset)
+                    children(offset.value)
                 }
                 val assumeLayoutBeforeDraw = @Composable { _: IntPx ->
                     // This assumes a layout was done before the draw pass.
@@ -1594,7 +1597,7 @@
         assertTrue(latch.await(1, TimeUnit.SECONDS))
         latch = CountDownLatch(1)
         activityTestRule.runOnUiThreadIR {
-            model.offset = 10.ipx
+            offset.value = 10.ipx
         }
         assertTrue(latch.await(1, TimeUnit.SECONDS))
     }
@@ -2030,7 +2033,7 @@
     fun layoutModifier_redrawsCorrectlyWhenOnlyNonModifiedSizeChanges() {
         val blue = Color(0xFF000080)
         val green = Color(0xFF00FF00)
-        val model = OffsetModel(10.ipx)
+        val offset = mutableStateOf(10.ipx)
 
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
@@ -2038,7 +2041,7 @@
                     drawRect(green)
                 }) {
                     FixedSize(
-                        model.offset,
+                        offset.value,
                         modifier = AlignTopLeft.drawLayer()
                             .drawBehind {
                                 drawLatch.countDown()
@@ -2053,7 +2056,7 @@
 
         drawLatch = CountDownLatch(1)
         activityTestRule.runOnUiThreadIR {
-            model.offset = 20.ipx
+            offset.value = 20.ipx
         }
         validateSquareColors(
             outerColor = green,
@@ -2287,7 +2290,7 @@
 
     @Test
     fun doubleDraw() {
-        val model = OffsetModel(0.ipx)
+        val offset = mutableStateOf(0.ipx)
         var outerLatch = CountDownLatch(1)
         activityTestRule.runOnUiThread {
             activity.setContent {
@@ -2298,8 +2301,8 @@
                     FixedSize(10.ipx, Modifier.drawBehind {
                         drawLine(
                             Color.Blue,
-                            Offset(model.offset.value.toFloat(), 0f),
-                            Offset(0f, model.offset.value.toFloat()),
+                            Offset(offset.value.value.toFloat(), 0f),
+                            Offset(0f, offset.value.value.toFloat()),
                             stroke = Stroke(width = 0.0f) // 0.0f represents hairline stroke
                         )
                         drawLatch.countDown()
@@ -2313,7 +2316,7 @@
         activityTestRule.runOnUiThread {
             drawLatch = CountDownLatch(1)
             outerLatch = CountDownLatch(1)
-            model.offset = 10.ipx
+            offset.value = 10.ipx
         }
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
         assertFalse(outerLatch.await(200, TimeUnit.MILLISECONDS))
@@ -2389,7 +2392,7 @@
         }
     }
 
-    private fun composeMovingSquaresWithRepaintBoundary(model: SquareModel, offset: OffsetModel) {
+    private fun composeMovingSquaresWithRepaintBoundary(model: SquareModel, offset: State<IntPx>) {
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 Position(
@@ -2407,7 +2410,7 @@
         }
     }
 
-    private fun composeMovingSquares(model: SquareModel, offset: OffsetModel) {
+    private fun composeMovingSquares(model: SquareModel, offset: State<IntPx>) {
         activityTestRule.runOnUiThreadIR {
             activity.setContent {
                 Position(
@@ -2487,7 +2490,7 @@
     @Composable
     fun Position(
         size: IntPx,
-        offset: OffsetModel,
+        offset: State<IntPx>,
         modifier: Modifier = Modifier,
         children: @Composable () -> Unit
     ) {
@@ -2497,7 +2500,7 @@
             }
             layout(size, size) {
                 placeables.forEach { child ->
-                    child.place(offset.offset, offset.offset)
+                    child.place(offset.value, offset.value)
                 }
                 positionLatch?.countDown()
             }
@@ -2737,7 +2740,7 @@
 fun Scroller(
     modifier: Modifier = Modifier,
     onScrollPositionChanged: (position: IntPx, maxPosition: IntPx) -> Unit,
-    offset: OffsetModel,
+    offset: State<IntPx>,
     child: @Composable () -> Unit
 ) {
     val maxPosition = state { IntPx.Infinity }
@@ -2746,7 +2749,7 @@
         maxPosition = maxPosition.value,
         >
             maxPosition.value = 0.ipx
-            onScrollPositionChanged(offset.offset, 0.ipx)
+            onScrollPositionChanged(offset.value, 0.ipx)
         },
         child = child
     )
@@ -2776,7 +2779,7 @@
 
 @Composable
 fun WrapForceRelayout(
-    model: OffsetModel,
+    model: State<IntPx>,
     modifier: Modifier = Modifier,
     children: @Composable () -> Unit
 ) {
@@ -2785,7 +2788,7 @@
         val width = placeables.maxBy { it.width.value }?.width ?: 0.ipx
         val height = placeables.maxBy { it.height.value }?.height ?: 0.ipx
         layout(width, height) {
-            model.offset
+            model.value
             placeables.forEach { it.place(0.ipx, 0.ipx) }
         }
     }
@@ -2903,18 +2906,16 @@
     }
 }
 
-@Model
+@Stable
 class SquareModel(
-    var size: IntPx = 10.ipx,
-    var outerColor: Color = Color(0xFF000080),
-    var innerColor: Color = Color(0xFFFFFFFF)
-)
-
-@Model
-class OffsetModel(var offset: IntPx)
-
-@Model
-class DoDraw(var value: Boolean = false)
+    size: IntPx = 10.ipx,
+    outerColor: Color = Color(0xFF000080),
+    innerColor: Color = Color(0xFFFFFFFF)
+) {
+    var size: IntPx by mutableStateOf(size)
+    var outerColor: Color by mutableStateOf(outerColor)
+    var innerColor: Color by mutableStateOf(innerColor)
+}
 
 // We only need this because IR compiler doesn't like converting lambdas to Runnables
 fun ActivityTestRule<*>.runOnUiThreadIR(block: () -> Unit) {
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
index ca59d04..9906002 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
@@ -29,7 +29,7 @@
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
 import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.espresso.Espresso
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
@@ -79,7 +79,7 @@
     @Test
     fun simpleLayoutTest() {
         val squareRef = Ref<ColoredSquareView>()
-        val squareSize = OffsetModel(100.ipx)
+        val squareSize = mutableStateOf(100.ipx)
         var expectedSize = 100
         composeTestRule.setContent {
             TestTag("content") {
@@ -87,7 +87,7 @@
                     Semantics(container = true) {
                         Layout(
                             @Composable {
-                                ColoredSquareView(size = squareSize.offset.value, ref = squareRef)
+                                ColoredSquareView(size = squareSize.value.value, ref = squareRef)
                             }
                         ) { measurables, constraints, _ ->
                             assertEquals(1, measurables.size)
@@ -114,7 +114,7 @@
 
         runOnUiThread {
             // Change view attribute using recomposition.
-            squareSize.offset = 200.ipx
+            squareSize.value = 200.ipx
             expectedSize = 200
         }
         findByTag("content").assertIsDisplayed()
@@ -139,7 +139,7 @@
     @Test
     fun simpleDrawTest() {
         val squareRef = Ref<ColoredSquareView>()
-        val colorModel = ColorModel(Color.Blue)
+        val colorModel = mutableStateOf(Color.Blue)
         val squareSize = 100
         var expectedColor = Color.Blue
         composeTestRule.setContent {
@@ -147,7 +147,7 @@
                 TestTag("content") {
                     Semantics(container = true) {
                         Container(Modifier.drawLayer()) {
-                            ColoredSquareView(color = colorModel.color, ref = squareRef)
+                            ColoredSquareView(color = colorModel.value, ref = squareRef)
                         }
                     }
                 }
@@ -173,7 +173,7 @@
 
         runOnUiThread {
             // Change view attribute using recomposition.
-            colorModel.color = Color.Green
+            colorModel.value = Color.Green
             expectedColor = Color.Green
         }
         Espresso
@@ -187,7 +187,7 @@
 
         runOnUiThread {
             // Change view attribute using the View reference.
-            colorModel.color = Color.Red
+            colorModel.value = Color.Red
             expectedColor = Color.Red
         }
         Espresso
@@ -333,10 +333,10 @@
         val heightMeasureSpecRef = Ref<Int>()
         // Unique starting constraints so that new constraints are different and thus recomp is
         // guaranteed.
-        val constraintsHolder = ConstraintsModel(Constraints.fixed(1234.ipx, 5678.ipx))
+        val constraintsHolder = mutableStateOf(Constraints.fixed(1234.ipx, 5678.ipx))
 
         composeTestRule.setContent {
-            Container(LayoutConstraints(constraintsHolder.constraints)) {
+            Container(LayoutConstraints(constraintsHolder.value)) {
                 MeasureSpecSaverView(
                     ref = viewRef,
                     widthMeasureSpecRef = widthMeasureSpecRef,
@@ -346,7 +346,7 @@
         }
 
         runOnUiThread {
-            constraintsHolder.constraints = constraints
+            constraintsHolder.value = constraints
             viewRef.value?.layoutParams = layoutParams
         }
 
@@ -359,14 +359,14 @@
     @Test
     fun testMeasurement_isDoneWithCorrectMinimumDimensionsSetOnView() {
         val viewRef = Ref<MeasureSpecSaverView>()
-        val constraintsHolder = ConstraintsModel(Constraints())
+        val constraintsHolder = mutableStateOf(Constraints())
         composeTestRule.setContent {
-            Container(LayoutConstraints(constraintsHolder.constraints)) {
+            Container(LayoutConstraints(constraintsHolder.value)) {
                 MeasureSpecSaverView(ref = viewRef)
             }
         }
         runOnUiThread {
-            constraintsHolder.constraints = Constraints(minWidth = 20.ipx, minHeight = 30.ipx)
+            constraintsHolder.value = Constraints(minWidth = 20.ipx, minHeight = 30.ipx)
         }
 
         runOnIdleCompose {
@@ -455,9 +455,3 @@
         }
     }
 }
-
-@Model
-private data class ColorModel(var color: Color)
-
-@Model
-private data class ConstraintsModel(var constraints: Constraints)
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ClipTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
index 87db4c1..30e6f0b 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Bitmap
 import android.os.Build
+import androidx.compose.mutableStateOf
 import androidx.test.filters.SdkSuppress
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
@@ -276,7 +277,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun switchFromRectToRounded() {
-        val model = ValueModel<Shape>(rectShape)
+        val model = mutableStateOf<Shape>(rectShape)
 
         rule.runOnUiThreadIR {
             activity.setContent {
@@ -311,7 +312,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun switchFromRectToPath() {
-        val model = ValueModel<Shape>(rectShape)
+        val model = mutableStateOf<Shape>(rectShape)
 
         rule.runOnUiThreadIR {
             activity.setContent {
@@ -338,7 +339,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun switchFromPathToRect() {
-        val model = ValueModel<Shape>(triangleShape)
+        val model = mutableStateOf<Shape>(triangleShape)
 
         rule.runOnUiThreadIR {
             activity.setContent {
@@ -365,7 +366,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun switchBetweenDifferentPaths() {
-        val model = ValueModel<Shape>(triangleShape)
+        val model = mutableStateOf<Shape>(triangleShape)
         // to be replaced with a DrawModifier wrapped into remember, so the recomposition
         // is not causing invalidation as the DrawModifier didn't change
         val drawCallback: DrawScope.() -> Unit = {
@@ -411,7 +412,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun emitClipLater() {
-        val model = ValueModel(false)
+        val model = mutableStateOf(false)
 
         rule.runOnUiThreadIR {
             activity.setContent {
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
index acb932a..c85a70d 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
@@ -174,7 +174,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun emitShadowLater() {
-        val model = ValueModel(false)
+        val model = mutableStateOf(false)
 
         rule.runOnUiThreadIR {
             activity.setContent {
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ModelReadsTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ModelReadsTest.kt
index 47d4837..95cb933 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ModelReadsTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ModelReadsTest.kt
@@ -17,6 +17,7 @@
 package androidx.ui.core.test
 
 import androidx.compose.FrameManager
+import androidx.compose.MutableState
 import androidx.compose.mutableStateOf
 import androidx.test.filters.SmallTest
 import androidx.test.rule.ActivityTestRule
@@ -57,19 +58,19 @@
 
     @Test
     fun useTheSameModelInDrawAndPosition() {
-        val model = OffsetModel(5.ipx)
+        val offset = mutableStateOf(5.ipx)
         var drawLatch = CountDownLatch(1)
         var positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
             activity.setContent {
                 Layout({}, modifier = Modifier.drawBehind {
                     // read from the model
-                    model.offset
+                    offset.value
                     drawLatch.countDown()
                 }) { _, _, _ ->
                     layout(10.ipx, 10.ipx) {
                         // read from the model
-                        model.offset
+                        offset.value
                         positionLatch.countDown()
                     }
                 }
@@ -81,7 +82,7 @@
         drawLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            model.offset = 7.ipx
+            offset.value = 7.ipx
         }
 
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
@@ -90,7 +91,7 @@
         drawLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            model.offset = 10.ipx
+            offset.value = 10.ipx
         }
 
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
@@ -99,20 +100,20 @@
 
     @Test
     fun useDifferentModelsInDrawAndPosition() {
-        val drawModel = OffsetModel(5.ipx)
-        val positionModel = OffsetModel(5.ipx)
+        val drawModel = mutableStateOf(5.ipx)
+        val positionModel = mutableStateOf(5.ipx)
         var drawLatch = CountDownLatch(1)
         var positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
             activity.setContent {
                 Layout({}, modifier = Modifier.drawBehind {
                     // read from the model
-                    drawModel.offset
+                    drawModel.value
                     drawLatch.countDown()
                 }) { _, _, _ ->
                     layout(10.ipx, 10.ipx) {
                         // read from the model
-                        positionModel.offset
+                        positionModel.value
                         positionLatch.countDown()
                     }
                 }
@@ -124,7 +125,7 @@
         drawLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            drawModel.offset = 7.ipx
+            drawModel.value = 7.ipx
         }
 
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
@@ -133,7 +134,7 @@
         drawLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            positionModel.offset = 10.ipx
+            positionModel.value = 10.ipx
         }
 
         assertTrue(positionLatch.await(1, TimeUnit.SECONDS))
@@ -142,19 +143,19 @@
 
     @Test
     fun useTheSameModelInMeasureAndPosition() {
-        val model = OffsetModel(5.ipx)
+        val offset = mutableStateOf(5.ipx)
         var measureLatch = CountDownLatch(1)
         var drawLatch = CountDownLatch(1)
         rule.runOnUiThread {
             activity.setContent {
                 Layout({}, modifier = Modifier.drawBehind {
                     // read from the model
-                    model.offset
+                    offset.value
                     drawLatch.countDown()
                 }) { _, _, _ ->
                     measureLatch.countDown()
                     // read from the model
-                    layout(model.offset, 10.ipx) {}
+                    layout(offset.value, 10.ipx) {}
                 }
             }
         }
@@ -164,7 +165,7 @@
         measureLatch = CountDownLatch(1)
         drawLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            model.offset = 10.ipx
+            offset.value = 10.ipx
         }
 
         assertTrue(measureLatch.await(1, TimeUnit.SECONDS))
@@ -173,7 +174,7 @@
         measureLatch = CountDownLatch(1)
         drawLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            model.offset = 15.ipx
+            offset.value = 15.ipx
         }
 
         assertTrue(measureLatch.await(1, TimeUnit.SECONDS))
@@ -182,8 +183,8 @@
 
     @Test
     fun useDifferentModelsInMeasureAndPosition() {
-        val measureModel = OffsetModel(5.ipx)
-        val positionModel = OffsetModel(5.ipx)
+        val measureModel = mutableStateOf(5.ipx)
+        val positionModel = mutableStateOf(5.ipx)
         var measureLatch = CountDownLatch(1)
         var positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
@@ -191,9 +192,9 @@
                 Layout({}) { _, _, _ ->
                     measureLatch.countDown()
                     // read from the model
-                    layout(measureModel.offset, 10.ipx) {
+                    layout(measureModel.value, 10.ipx) {
                         // read from the model
-                        positionModel.offset
+                        positionModel.value
                         positionLatch.countDown()
                     }
                 }
@@ -205,7 +206,7 @@
         measureLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            measureModel.offset = 10.ipx
+            measureModel.value = 10.ipx
         }
 
         assertTrue(measureLatch.await(1, TimeUnit.SECONDS))
@@ -215,7 +216,7 @@
         measureLatch = CountDownLatch(1)
         positionLatch = CountDownLatch(1)
         rule.runOnUiThread {
-            positionModel.offset = 15.ipx
+            positionModel.value = 15.ipx
         }
 
         assertFalse(measureLatch.await(200, TimeUnit.MILLISECONDS))
@@ -224,8 +225,8 @@
 
     @Test
     fun drawReactsOnCorrectModelsChanges() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 AtLeastSize(10.ipx, modifier = Modifier.drawBehind {
@@ -243,8 +244,8 @@
 
     @Test
     fun measureReactsOnCorrectModelsChanges() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 Layout({}) { _, _, _ ->
@@ -264,8 +265,8 @@
 
     @Test
     fun layoutReactsOnCorrectModelsChanges() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 Layout({}) { _, _, _ ->
@@ -286,8 +287,8 @@
 
     @Test
     fun drawStopsReactingOnModelsAfterDetaching() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 val modifier = if (enabled.value) {
@@ -307,8 +308,8 @@
 
     @Test
     fun measureStopsReactingOnModelsAfterDetaching() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 if (enabled.value) {
@@ -328,8 +329,8 @@
 
     @Test
     fun layoutStopsReactingOnModelsAfterDetaching() {
-        val enabled = ValueModel(true)
-        val model = ValueModel(0)
+        val enabled = mutableStateOf(true)
+        val model = mutableStateOf(0)
         rule.runOnUiThread {
             activity.setContent {
                 if (enabled.value) {
@@ -490,8 +491,8 @@
     }
 
     fun assertCountDownOnlyWhileEnabled(
-        enableModel: ValueModel<Boolean>,
-        valueModel: ValueModel<Int>,
+        enableModel: MutableState<Boolean>,
+        valueModel: MutableState<Int>,
         triggeredByEnableSwitch: Boolean = true
     ) {
         latch = CountDownLatch(1)
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
index 5a14bf0..7ac8d3b 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
@@ -137,14 +137,14 @@
     @Test
     fun switchFromHalfOpacityToFull() {
         val color = Color.Green
-        val model = ValueModel(0.5f)
+        val opacity = mutableStateOf(0.5f)
 
         rule.runOnUiThreadIR {
             activity.setContent {
                 AtLeastSize(
                     size = 10.ipx,
                     modifier = Modifier.background(Color.White)
-                        .drawOpacity(model.value)
+                        .drawOpacity(opacity.value)
                         .plus(unlatch)
                         .background(color)
                 ) {
@@ -154,7 +154,7 @@
         assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
 
         rule.runOnUiThreadIR {
-            model.value = 1f
+            opacity.value = 1f
         }
 
         takeScreenShot(10).apply {
@@ -195,7 +195,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun emitDrawWithOpacityLater() {
-        val model = ValueModel(false)
+        val model = mutableStateOf(false)
 
         rule.runOnUiThreadIR {
             activity.setContent {
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ValueModel.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ValueModel.kt
deleted file mode 100644
index 27dc87c..0000000
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/ValueModel.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.ui.core.test
-
-import androidx.compose.Model
-
-@Model
-data class ValueModel<T>(var value: T)
\ No newline at end of file
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
index f7d19a8..8598aeb 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
@@ -199,13 +199,13 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun requestLayoutDuringLayout() {
-        val offset = OffsetModel(0.ipx)
+        val offset = mutableStateOf(0.ipx)
         rule.runOnUiThreadIR {
             activity.setContent {
                 Scroller(
                     modifier = countdownLatchBackgroundModifier(Color.Yellow),
                      position, _ ->
-                        offset.offset = position
+                        offset.value = position
                     },
                     offset = offset
                 ) {
@@ -223,7 +223,7 @@
 
     @Test
     fun subcomposionInsideWithConstraintsDoesntAffectModelReadsObserving() {
-        val model = ValueModel(0)
+        val model = mutableStateOf(0)
         var latch = CountDownLatch(1)
 
         rule.runOnUiThreadIR {
@@ -261,7 +261,7 @@
 
     @Test
     fun withConstraintCallbackIsNotExecutedWithInnerRecompositions() {
-        val model = ValueModel(0)
+        val model = mutableStateOf(0)
         var latch = CountDownLatch(1)
         var recompositionsCount1 = 0
         var recompositionsCount2 = 0
@@ -289,7 +289,7 @@
 
     @Test
     fun updateConstraintsRecomposingWithConstraints() {
-        val model = ValueModel(50.ipx)
+        val model = mutableStateOf(50.ipx)
         var latch = CountDownLatch(1)
         var actualConstraints: Constraints? = null
 
@@ -345,7 +345,7 @@
 
     @Test
     fun withConstsraintsBehavesAsWrap() {
-        val size = ValueModel(50.ipx)
+        val size = mutableStateOf(50.ipx)
         var withConstLatch = CountDownLatch(1)
         var childLatch = CountDownLatch(1)
         var withConstSize: IntPxSize? = null
@@ -398,7 +398,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun withConstraintsIsNotSwallowingInnerRemeasureRequest() {
-        val model = ValueModel(100.ipx)
+        val model = mutableStateOf(100.ipx)
 
         rule.runOnUiThreadIR {
             activity.setContent {
@@ -468,7 +468,7 @@
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
     @Test
     fun removeLayoutNodeFromWithConstraintsDuringOnMeasure() {
-        val model = ValueModel(100.ipx)
+        val model = mutableStateOf(100.ipx)
         drawLatch = CountDownLatch(2)
 
         rule.runOnUiThreadIR {
@@ -884,7 +884,7 @@
 }
 
 @Composable
-private fun ChangingConstraintsLayout(size: ValueModel<IntPx>, children: @Composable () -> Unit) {
+private fun ChangingConstraintsLayout(size: State<IntPx>, children: @Composable () -> Unit) {
     Layout(children) { measurables, _, _ ->
         layout(100.ipx, 100.ipx) {
             val constraints = Constraints.fixed(size.value, size.value)
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/res/ResourcesTest.kt b/ui/ui-core/src/androidTest/java/androidx/ui/res/ResourcesTest.kt
index 87e8e54..39f6ffb 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/res/ResourcesTest.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/res/ResourcesTest.kt
@@ -97,7 +97,7 @@
         runOnIdleCompose {
             pendingExecutor.runNow() // load the resource
             assertThat(uiThreadWork).isNotNull()
-            // update @Model object so that recompose is expected to be triggered.
+            // update state object so that recompose is expected to be triggered.
             uiThreadWork?.invoke()
         }
 
@@ -156,7 +156,7 @@
         runOnIdleCompose {
             pendingExecutor.runNow() // load the resource
             assertThat(uiThreadWork).isNotNull()
-            // update @Model object so that recompose is expected to be triggered.
+            // update state object so that recompose is expected to be triggered.
             uiThreadWork?.invoke()
         }
 
diff --git a/ui/ui-core/src/androidTest/java/androidx/ui/semantics/SemanticsTests.kt b/ui/ui-core/src/androidTest/java/androidx/ui/semantics/SemanticsTests.kt
index 8a50d6e..2b7c833 100644
--- a/ui/ui-core/src/androidTest/java/androidx/ui/semantics/SemanticsTests.kt
+++ b/ui/ui-core/src/androidTest/java/androidx/ui/semantics/SemanticsTests.kt
@@ -17,10 +17,10 @@
 package androidx.ui.semantics
 
 import androidx.compose.Composable
+import androidx.compose.mutableStateOf
 import androidx.compose.remember
 import androidx.test.filters.MediumTest
 import androidx.ui.core.Layout
-import androidx.ui.core.test.ValueModel
 import androidx.ui.test.SemanticsNodeInteraction
 import androidx.ui.test.SemanticsMatcher
 import androidx.ui.test.assertCountEquals
@@ -64,7 +64,7 @@
     @Test
     fun removingMergedSubtree_updatesSemantics() {
         val label = "foo"
-        val showSubtree = ValueModel(true)
+        val showSubtree = mutableStateOf(true)
         composeTestRule.setContent {
             Semantics(container = true, properties = {
                 testTag = TestTag
@@ -95,7 +95,7 @@
     fun addingNewMergedNode_updatesSemantics() {
         val label = "foo"
         val value = "bar"
-        val showNewNode = ValueModel(false)
+        val showNewNode = mutableStateOf(false)
         composeTestRule.setContent {
             Semantics(container = true, properties = {
                 testTag = TestTag
@@ -134,7 +134,7 @@
     @Test
     fun removingSubtreeWithoutSemanticsAsTopNode_updatesSemantics() {
         val label = "foo"
-        val showSubtree = ValueModel(true)
+        val showSubtree = mutableStateOf(true)
         composeTestRule.setContent {
             Semantics(container = true, properties = {
                 testTag = TestTag
@@ -165,7 +165,7 @@
     fun changingStackedSemanticsComponent_updatesSemantics() {
         val beforeLabel = "before"
         val afterLabel = "after"
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
         composeTestRule.setContent {
             Semantics(container = true, properties = {
                 testTag = TestTag
@@ -190,7 +190,7 @@
     fun changingStackedSemanticsComponent_notTopMost_updatesSemantics() {
         val beforeLabel = "before"
         val afterLabel = "after"
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
 
         composeTestRule.setContent {
             Semantics(container = true, properties = { testTag = "don't care" }) {
@@ -220,7 +220,7 @@
     fun changingSemantics_belowStackedLayoutNodes_updatesCorrectly() {
         val beforeLabel = "before"
         val afterLabel = "after"
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
 
         composeTestRule.setContent {
             SimpleTestLayout {
@@ -247,7 +247,7 @@
     fun changingSemantics_belowNodeMergedThroughBoundary_updatesCorrectly() {
         val beforeLabel = "before"
         val afterLabel = "after"
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
 
         composeTestRule.setContent {
             Semantics(properties = { testTag = TestTag }) {
@@ -316,7 +316,7 @@
 
         val beforeLabel = "before"
         val afterLabel = "after"
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
 
         composeTestRule.setContent {
             Semantics(container = true, properties = {
@@ -352,7 +352,7 @@
         val beforeAction = { println("this never gets called") }
         val afterAction = { println("neither does this") }
 
-        val isAfter = ValueModel(false)
+        val isAfter = mutableStateOf(false)
 
         composeTestRule.setContent {
             Semantics(container = true, properties = {
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/ModelObserver.kt b/ui/ui-core/src/main/java/androidx/ui/core/ModelObserver.kt
index 6fbb66c..b946336 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/ModelObserver.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/ModelObserver.kt
@@ -31,7 +31,7 @@
  *
  * @sample androidx.ui.core.samples.modelObserverExample
  *
- * When a `@Model` class change has been committed, the `onCommit` listener will be called
+ * When a state change has been committed, the `onCommit` listener will be called
  * with the `targetObject` as the argument. There are no order guarantees for
  * `onCommit` listener calls. Commit callbacks are made on the thread that model changes
  * are committed, so the [commitExecutor] allows the developer to control the thread on which the
diff --git a/ui/ui-core/src/main/java/androidx/ui/res/Resources.kt b/ui/ui-core/src/main/java/androidx/ui/res/Resources.kt
index 15315fa..f53d035 100644
--- a/ui/ui-core/src/main/java/androidx/ui/res/Resources.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/res/Resources.kt
@@ -21,8 +21,11 @@
 import android.util.LruCache
 import androidx.annotation.GuardedBy
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
 import androidx.compose.remember
+import androidx.compose.setValue
 import java.util.concurrent.Executor
 import java.util.concurrent.Executors
 
@@ -46,13 +49,15 @@
 /**
  * A class used for the result of the asynchronous resource loading.
  */
-@Model class DeferredResource<T> internal constructor(
-    internal var state: LoadingState = LoadingState.PENDING,
+@Stable
+class DeferredResource<T> internal constructor(
+    state: LoadingState = LoadingState.PENDING,
     private val pendingResource: T? = null,
     private val failedResource: T? = null
 ) {
-    private var loadedResource: T? = null
-    private var failedReason: Throwable? = null
+    internal var state by mutableStateOf(state)
+    private var loadedResource: T? by mutableStateOf<T?>(null)
+    private var failedReason: Throwable? by mutableStateOf<Throwable?>(null)
 
     internal fun loadCompleted(loadedResource: T) {
         state = LoadingState.LOADED
diff --git a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerDragTest.kt b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerDragTest.kt
index b9559d4..9261cb2 100644
--- a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerDragTest.kt
+++ b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerDragTest.kt
@@ -83,7 +83,7 @@
 
     @Before
     fun setup() {
-        open(false) // we open a Frame so @Model reads are allowed
+        open(false) // we open a Frame so state reads are allowed
 
         selectionRegistrar.subscribe(selectable)
 
diff --git a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerLongPressDragTest.kt b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerLongPressDragTest.kt
index 6d058cb..7079fb1 100644
--- a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerLongPressDragTest.kt
+++ b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerLongPressDragTest.kt
@@ -80,7 +80,7 @@
 
     @Before
     fun setup() {
-        open(false) // we open a Frame so @Model reads are allowed
+        open(false) // we open a Frame so state reads are allowed
         val containerLayoutCoordinates = mock<LayoutCoordinates> {
             on { isAttached } doReturn true
         }
diff --git a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerTest.kt b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerTest.kt
index 7a37b58..8b7bcdf 100644
--- a/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerTest.kt
+++ b/ui/ui-core/src/test/java/androidx/ui/core/selection/SelectionManagerTest.kt
@@ -84,7 +84,7 @@
 
     @Before
     fun setup() {
-        open(false) // we open a Frame so @Model reads are allowed
+        open(false) // we open a Frame so state reads are allowed
         selectionRegistrar.subscribe(selectable)
         selectionManager.containerLayoutCoordinates = containerLayoutCoordinates
         selectionManager.hapticFeedBack = hapticFeedback
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DeterminateProgressTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DeterminateProgressTest.kt
index 59b3a0a..924d435 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DeterminateProgressTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/DeterminateProgressTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.ui.foundation
 
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.filters.MediumTest
 import androidx.ui.core.Modifier
 import androidx.ui.core.TestTag
@@ -34,11 +34,6 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-@Model
-private class State {
-    var progress = 0f
-}
-
 @MediumTest
 @RunWith(JUnit4::class)
 class DeterminateProgressTest {
@@ -49,12 +44,12 @@
     @Test
     fun determinateProgress_testSemantics() {
         val tag = "linear"
-        val state = State()
+        val progress = mutableStateOf(0f)
 
         composeTestRule
             .setContent {
                 TestTag(tag = tag) {
-                    DeterminateProgressIndicator(progress = state.progress) {
+                    DeterminateProgressIndicator(progress = progress.value) {
                         Box(Modifier.preferredSize(50.dp).drawBackground(Color.Cyan))
                     }
                 }
@@ -65,7 +60,7 @@
             .assertRangeInfoEquals(AccessibilityRangeInfo(0f, 0f..1f))
 
         runOnUiThread {
-            state.progress = 0.5f
+            progress.value = 0.5f
         }
 
         findByTag(tag)
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
index c17e80a..cc62f65 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
@@ -17,7 +17,7 @@
 package androidx.ui.layout.test
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Alignment
 import androidx.ui.core.Layout
@@ -357,7 +357,7 @@
     @Test
     fun testContainer_childAffectsContainerSize() {
         var layoutLatch = CountDownLatch(2)
-        val model = SizeModel(10.dp)
+        val size = mutableStateOf(10.dp)
         var measure = 0
         var layout = 0
         show {
@@ -365,7 +365,7 @@
                 Layout(children = {
                     Container {
                         EmptyBox(
-                            width = model.size,
+                            width = size.value,
                             height = 10.dp,
                             modifier = Modifier.onPositioned { layoutLatch.countDown() }
                         )
@@ -386,7 +386,7 @@
         assertEquals(1, layout)
 
         layoutLatch = CountDownLatch(2)
-        activityTestRule.runOnUiThread { model.size = 20.dp }
+        activityTestRule.runOnUiThread { size.value = 20.dp }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(2, measure)
         assertEquals(2, layout)
@@ -395,7 +395,7 @@
     @Test
     fun testContainer_childDoesNotAffectContainerSize_whenSizeIsMax() {
         var layoutLatch = CountDownLatch(2)
-        val model = SizeModel(10.dp)
+        val size = mutableStateOf(10.dp)
         var measure = 0
         var layout = 0
         show {
@@ -403,7 +403,7 @@
                 Layout(children = {
                     Container(expanded = true) {
                         EmptyBox(
-                            width = model.size,
+                            width = size.value,
                             height = 10.dp,
                             modifier = Modifier.onPositioned { layoutLatch.countDown() }
                         )
@@ -424,7 +424,7 @@
         assertEquals(1, layout)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThread { model.size = 20.dp }
+        activityTestRule.runOnUiThread { size.value = 20.dp }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(1, measure)
         assertEquals(1, layout)
@@ -433,7 +433,7 @@
     @Test
     fun testContainer_childDoesNotAffectContainerSize_whenFixedWidthAndHeight() {
         var layoutLatch = CountDownLatch(2)
-        val model = SizeModel(10.dp)
+        val size = mutableStateOf(10.dp)
         var measure = 0
         var layout = 0
         show {
@@ -441,7 +441,7 @@
                 Layout(children = {
                     Container(width = 20.dp, height = 20.dp) {
                         EmptyBox(
-                            width = model.size,
+                            width = size.value,
                             height = 10.dp,
                             modifier = Modifier.onPositioned { layoutLatch.countDown() }
                         )
@@ -462,7 +462,7 @@
         assertEquals(1, layout)
 
         layoutLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThread { model.size = 20.dp }
+        activityTestRule.runOnUiThread { size.value = 20.dp }
         assertTrue(layoutLatch.await(1, TimeUnit.SECONDS))
         assertEquals(1, measure)
         assertEquals(1, layout)
@@ -478,6 +478,3 @@
         }
     }
 }
-
-@Model
-data class SizeModel(var size: Dp)
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/OnPositionedTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/OnPositionedTest.kt
index 3bd6d1f..3c5b9ce 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/OnPositionedTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/OnPositionedTest.kt
@@ -18,9 +18,10 @@
 
 import android.widget.FrameLayout
 import androidx.compose.Composable
-import androidx.compose.Model
 import androidx.compose.Recomposer
+import androidx.compose.State
 import androidx.compose.emptyContent
+import androidx.compose.mutableStateOf
 import androidx.test.filters.SmallTest
 import androidx.ui.core.Layout
 import androidx.ui.core.LayoutCoordinates
@@ -35,6 +36,7 @@
 import androidx.ui.layout.Stack
 import androidx.ui.layout.fillMaxSize
 import androidx.ui.layout.padding
+import androidx.ui.unit.Dp
 import androidx.ui.unit.Px
 import androidx.ui.unit.PxPosition
 import androidx.ui.unit.dp
@@ -215,7 +217,7 @@
 
     @Test
     fun justAddedOnPositionedCallbackFiredWithoutLayoutChanges() = with(density) {
-        val needCallback = NeedCallback(false)
+        val needCallback = mutableStateOf(false)
 
         val positionedLatch = CountDownLatch(1)
         show {
@@ -234,7 +236,7 @@
 
     @Test
     fun testRepositionTriggersCallback() {
-        val modelLeft = SizeModel(30.dp)
+        val left = mutableStateOf(30.dp)
         var realLeft: Px? = null
 
         var positionedLatch = CountDownLatch(1)
@@ -246,7 +248,7 @@
                         positionedLatch.countDown()
                     }
                         .fillMaxSize()
-                        .padding(start = modelLeft.size),
+                        .padding(start = left.value),
                     children = emptyContent()
                 )
             }
@@ -254,7 +256,7 @@
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
 
         positionedLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThread { modelLeft.size = 40.dp }
+        activityTestRule.runOnUiThread { left.value = 40.dp }
 
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
         with(density) {
@@ -267,12 +269,12 @@
         // when we reposition any parent layout is causes the change in global
         // position of all the children down the tree(for example during the scrolling).
         // children should be able to react on this change.
-        val modelLeft = SizeModel(20.dp)
+        val left = mutableStateOf(20.dp)
         var realLeft: Px? = null
         var positionedLatch = CountDownLatch(1)
         show {
             Stack {
-                Offset(modelLeft) {
+                Offset(left) {
                     Container(width = 10.dp, height = 10.dp) {
                         Container(width = 10.dp, height = 10.dp) {
                             Container(
@@ -292,7 +294,7 @@
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
 
         positionedLatch = CountDownLatch(1)
-        activityTestRule.runOnUiThread { modelLeft.size = 40.dp }
+        activityTestRule.runOnUiThread { left.value = 40.dp }
 
         assertTrue(positionedLatch.await(1, TimeUnit.SECONDS))
         with(density) {
@@ -319,15 +321,12 @@
     }
 
     @Composable
-    private fun Offset(sizeModel: SizeModel, children: @Composable () -> Unit) {
+    private fun Offset(sizeModel: State<Dp>, children: @Composable () -> Unit) {
         // simple copy of Padding which doesn't recompose when the size changes
         Layout(children) { measurables, constraints, _ ->
             layout(constraints.maxWidth, constraints.maxHeight) {
-                measurables.first().measure(constraints).place(sizeModel.size.toPx(), 0.px)
+                measurables.first().measure(constraints).place(sizeModel.value.toPx(), 0.px)
             }
         }
     }
 }
-
-@Model
-private data class NeedCallback(var value: Boolean)
diff --git a/ui/ui-material/api/0.1.0-dev12.txt b/ui/ui-material/api/0.1.0-dev12.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/0.1.0-dev12.txt
+++ b/ui/ui-material/api/0.1.0-dev12.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/api/current.txt b/ui/ui-material/api/current.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/current.txt
+++ b/ui/ui-material/api/current.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/api/public_plus_experimental_0.1.0-dev12.txt b/ui/ui-material/api/public_plus_experimental_0.1.0-dev12.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/public_plus_experimental_0.1.0-dev12.txt
+++ b/ui/ui-material/api/public_plus_experimental_0.1.0-dev12.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/api/public_plus_experimental_current.txt b/ui/ui-material/api/public_plus_experimental_current.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/public_plus_experimental_current.txt
+++ b/ui/ui-material/api/public_plus_experimental_current.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/api/restricted_0.1.0-dev12.txt b/ui/ui-material/api/restricted_0.1.0-dev12.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/restricted_0.1.0-dev12.txt
+++ b/ui/ui-material/api/restricted_0.1.0-dev12.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/api/restricted_current.txt b/ui/ui-material/api/restricted_current.txt
index 0e65efa..a580938 100644
--- a/ui/ui-material/api/restricted_current.txt
+++ b/ui/ui-material/api/restricted_current.txt
@@ -206,6 +206,8 @@
     method public boolean isDrawerGesturesEnabled();
     method public void setDrawerGesturesEnabled(boolean p);
     method public void setDrawerState(androidx.ui.material.DrawerState p);
+    property public final androidx.ui.material.DrawerState drawerState;
+    property public final boolean isDrawerGesturesEnabled;
   }
 
   public final class Shapes {
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
index 93ae9fc..414841b 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DynamicThemeActivity.kt
@@ -20,7 +20,8 @@
 import androidx.activity.ComponentActivity
 import androidx.animation.FastOutSlowInEasing
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.MutableState
+import androidx.compose.mutableStateOf
 import androidx.compose.remember
 import androidx.ui.core.Modifier
 import androidx.ui.core.setContent
@@ -53,12 +54,12 @@
  * as the user scrolls. This has the effect of going from a 'light' theme to a 'dark' theme.
  */
 class DynamicThemeActivity : ComponentActivity() {
-    private val scrollFraction = ScrollFraction()
+    private val scrollFraction = mutableStateOf(0f)
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContent {
-            val palette = interpolateTheme(scrollFraction.fraction)
+            val palette = interpolateTheme(scrollFraction.value)
             val darkenedPrimary = palette.darkenedPrimary
             window.statusBarColor = darkenedPrimary
             window.navigationBarColor = darkenedPrimary
@@ -79,8 +80,7 @@
         }
 }
 
-@Model
-private class ScrollFraction(var fraction: Float = 0f)
+private typealias ScrollFraction = MutableState<Float>
 
 @Composable
 private fun DynamicThemeApp(scrollFraction: ScrollFraction, palette: ColorPalette) {
@@ -88,7 +88,7 @@
         val scrollerPosition = ScrollerPosition()
         val fraction =
             round((scrollerPosition.value / scrollerPosition.maxPosition) * 100) / 100
-        remember(fraction) { scrollFraction.fraction = fraction }
+        remember(fraction) { scrollFraction.value = fraction }
         Scaffold(
             topAppBar = { TopAppBar({ Text("Scroll down!") }) },
             bottomAppBar = { BottomAppBar(fabConfiguration = it, cutoutShape = CircleShape) {} },
@@ -109,7 +109,7 @@
 
 @Composable
 private fun Fab(scrollFraction: ScrollFraction) {
-    val fabText = emojiForScrollFraction(scrollFraction.fraction)
+    val fabText = emojiForScrollFraction(scrollFraction.value)
     ExtendedFloatingActionButton(
         text = { Text(fabText, style = MaterialTheme.typography.h5) },
         >
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
index 0219b37..613d4e2 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/DrawerTest.kt
@@ -17,8 +17,8 @@
 package androidx.ui.material
 
 import android.os.SystemClock.sleep
-import androidx.compose.Model
 import androidx.compose.emptyContent
+import androidx.compose.mutableStateOf
 import androidx.test.filters.MediumTest
 import androidx.ui.core.LayoutCoordinates
 import androidx.ui.core.Modifier
@@ -53,9 +53,6 @@
 import java.util.concurrent.TimeUnit
 import kotlin.math.roundToInt
 
-@Model
-data class DrawerStateHolder(var state: DrawerState)
-
 @MediumTest
 @RunWith(JUnit4::class)
 class DrawerTest {
@@ -154,11 +151,11 @@
         var contentWidth: IntPx? = null
         var openedLatch: CountDownLatch? = null
         var closedLatch: CountDownLatch? = CountDownLatch(1)
-        val drawerState = DrawerStateHolder(DrawerState.Closed)
+        val drawerState = mutableStateOf(DrawerState.Closed)
         composeTestRule.setMaterialContent {
             TestTag("Drawer") {
                 Semantics(container = true) {
-                    ModalDrawerLayout(drawerState.state, { drawerState.state = it },
+                    ModalDrawerLayout(drawerState.value, { drawerState.value = it },
                         drawerContent = {
                             Box(
                                 Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
@@ -186,7 +183,7 @@
         // When the drawer state is set to Opened
         openedLatch = CountDownLatch(1)
         runOnIdleCompose {
-            drawerState.state = DrawerState.Opened
+            drawerState.value = DrawerState.Opened
         }
         // Then the drawer should be opened
         assertThat(openedLatch.await(5, TimeUnit.SECONDS)).isTrue()
@@ -194,7 +191,7 @@
         // When the drawer state is set to Closed
         closedLatch = CountDownLatch(1)
         runOnIdleCompose {
-            drawerState.state = DrawerState.Closed
+            drawerState.value = DrawerState.Closed
         }
         // Then the drawer should be closed
         assertThat(closedLatch.await(5, TimeUnit.SECONDS)).isTrue()
@@ -204,12 +201,12 @@
     fun modalDrawer_bodyContent_clickable() {
         var drawerClicks = 0
         var bodyClicks = 0
-        val drawerState = DrawerStateHolder(DrawerState.Closed)
+        val drawerState = mutableStateOf(DrawerState.Closed)
         composeTestRule.setMaterialContent {
             // emulate click on the screen
             TestTag("Drawer") {
                 Semantics(container = true) {
-                    ModalDrawerLayout(drawerState.state, { drawerState.state = it },
+                    ModalDrawerLayout(drawerState.value, { drawerState.value = it },
                         drawerContent = {
                             Clickable( drawerClicks += 1 }) {
                                 Box(Modifier.fillMaxSize(), children = emptyContent())
@@ -231,7 +228,7 @@
             assertThat(drawerClicks).isEqualTo(0)
             assertThat(bodyClicks).isEqualTo(1)
 
-            drawerState.state = DrawerState.Opened
+            drawerState.value = DrawerState.Opened
         }
         sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
 
@@ -255,11 +252,11 @@
         var openedHeight: IntPx? = null
         var openedLatch: CountDownLatch? = null
         var closedLatch: CountDownLatch? = CountDownLatch(1)
-        val drawerState = DrawerStateHolder(DrawerState.Closed)
+        val drawerState = mutableStateOf(DrawerState.Closed)
         composeTestRule.setMaterialContent {
             TestTag("Drawer") {
                 Semantics(container = true) {
-                    BottomDrawerLayout(drawerState.state, { drawerState.state = it },
+                    BottomDrawerLayout(drawerState.value, { drawerState.value = it },
                         drawerContent = {
                             Box(Modifier.fillMaxSize().onPositioned { info: LayoutCoordinates ->
                                 val pos = info.localToGlobal(PxPosition.Origin)
@@ -288,7 +285,7 @@
         // When the drawer state is set to Opened
         openedLatch = CountDownLatch(1)
         runOnIdleCompose {
-            drawerState.state = DrawerState.Opened
+            drawerState.value = DrawerState.Opened
         }
         // Then the drawer should be opened
         assertThat(openedLatch.await(5, TimeUnit.SECONDS)).isTrue()
@@ -296,7 +293,7 @@
         // When the drawer state is set to Closed
         closedLatch = CountDownLatch(1)
         runOnIdleCompose {
-            drawerState.state = DrawerState.Closed
+            drawerState.value = DrawerState.Closed
         }
         // Then the drawer should be closed
         assertThat(closedLatch.await(5, TimeUnit.SECONDS)).isTrue()
@@ -306,12 +303,12 @@
     fun bottomDrawer_bodyContent_clickable() {
         var drawerClicks = 0
         var bodyClicks = 0
-        val drawerState = DrawerStateHolder(DrawerState.Closed)
+        val drawerState = mutableStateOf(DrawerState.Closed)
         composeTestRule.setMaterialContent {
             // emulate click on the screen
             TestTag("Drawer") {
                 Semantics(container = true) {
-                    BottomDrawerLayout(drawerState.state, { drawerState.state = it },
+                    BottomDrawerLayout(drawerState.value, { drawerState.value = it },
                         drawerContent = {
                             Clickable( drawerClicks += 1 }) {
                                 Box(Modifier.fillMaxSize(), children = emptyContent())
@@ -335,7 +332,7 @@
         }
 
         runOnUiThread {
-            drawerState.state = DrawerState.Opened
+            drawerState.value = DrawerState.Opened
         }
         sleep(100) // TODO(147586311): remove this sleep when opening the drawer triggers a wait
 
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ProgressIndicatorTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ProgressIndicatorTest.kt
index fd9ab03..9df7c78 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ProgressIndicatorTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ProgressIndicatorTest.kt
@@ -15,7 +15,7 @@
  */
 package androidx.ui.material
 
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.filters.LargeTest
 import androidx.ui.core.TestTag
 import androidx.ui.foundation.Strings
@@ -33,11 +33,6 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-@Model
-private class State {
-    var progress = 0f
-}
-
 @LargeTest
 @RunWith(JUnit4::class)
 class ProgressIndicatorTest {
@@ -51,12 +46,12 @@
     @Test
     fun determinateLinearProgressIndicator_Progress() {
         val tag = "linear"
-        val state = State()
+        val progress = mutableStateOf(0f)
 
         composeTestRule
             .setMaterialContent {
                 TestTag(tag = tag) {
-                    LinearProgressIndicator(progress = state.progress)
+                    LinearProgressIndicator(progress = progress.value)
                 }
             }
 
@@ -66,7 +61,7 @@
             .assertRangeInfoEquals(AccessibilityRangeInfo(0f, 0f..1f))
 
         runOnUiThread {
-            state.progress = 0.5f
+            progress.value = 0.5f
         }
 
         findByTag(tag)
@@ -115,12 +110,12 @@
     @Test
     fun determinateCircularProgressIndicator_Progress() {
         val tag = "circular"
-        val state = State()
+        val progress = mutableStateOf(0f)
 
         composeTestRule
             .setMaterialContent {
                 TestTag(tag = tag) {
-                    CircularProgressIndicator(progress = state.progress)
+                    CircularProgressIndicator(progress = progress.value)
                 }
             }
 
@@ -130,7 +125,7 @@
             .assertRangeInfoEquals(AccessibilityRangeInfo(0f, 0f..1f))
 
         runOnUiThread {
-            state.progress = 0.5f
+            progress.value = 0.5f
         }
 
         findByTag(tag)
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
index 38f0b7d..38a7691 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/RadioGroupUiTest.kt
@@ -17,7 +17,7 @@
 package androidx.ui.material
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.test.filters.MediumTest
 import androidx.ui.core.TestTag
 import androidx.ui.foundation.Strings
@@ -36,9 +36,6 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-@Model
-internal class RadioGroupSelectedState<T>(var selected: T)
-
 @MediumTest
 @RunWith(JUnit4::class)
 class RadioGroupUiTest {
@@ -73,7 +70,7 @@
 
     @Test
     fun radioGroupTest_defaultSemantics() {
-        val select = RadioGroupSelectedState(itemOne)
+        val selected = mutableStateOf(itemOne)
 
         composeTestRule.setMaterialContent {
             VerticalRadioGroupforTests {
@@ -81,8 +78,8 @@
                     TestTag(tag = item) {
                         RadioGroupTextItem(
                             text = item,
-                            selected = (select.selected == item),
-                             select.selected = item })
+                            selected = (selected.value == item),
+                             selected.value = item })
                     }
                 }
             }
@@ -95,7 +92,7 @@
 
     @Test
     fun radioGroupTest_ensureUnselectable() {
-        val select = RadioGroupSelectedState(itemOne)
+        val selected = mutableStateOf(itemOne)
 
         composeTestRule.setMaterialContent {
             VerticalRadioGroupforTests {
@@ -103,8 +100,8 @@
                     TestTag(tag = item) {
                         RadioGroupTextItem(
                             text = item,
-                            selected = (select.selected == item),
-                             select.selected = item })
+                            selected = (selected.value == item),
+                             selected.value = item })
                     }
                 }
             }
@@ -124,15 +121,15 @@
 
     @Test
     fun radioGroupTest_clickSelect() {
-        val select = RadioGroupSelectedState(itemOne)
+        val selected = mutableStateOf(itemOne)
         composeTestRule.setMaterialContent {
             VerticalRadioGroupforTests {
                 options.forEach { item ->
                     TestTag(tag = item) {
                         RadioGroupTextItem(
                             text = item,
-                            selected = (select.selected == item),
-                             select.selected = item })
+                            selected = (selected.value == item),
+                             selected.value = item })
                     }
                 }
             }
@@ -151,7 +148,7 @@
 
     @Test
     fun radioGroupTest_clickSelectTwoDifferentItems() {
-        val select = RadioGroupSelectedState(itemOne)
+        val selected = mutableStateOf(itemOne)
 
         composeTestRule.setMaterialContent {
             VerticalRadioGroupforTests {
@@ -159,8 +156,8 @@
                     TestTag(tag = item) {
                         RadioGroupTextItem(
                             text = item,
-                            selected = (select.selected == item),
-                             select.selected = item })
+                            selected = (selected.value == item),
+                             selected.value = item })
                     }
                 }
             }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Color.kt b/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
index 7ccf65b..eae3e7c 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Color.kt
@@ -219,7 +219,7 @@
  * components that consume the specific color(s) that have been changed - so this default
  * implementation is intended to be memoized in the ambient, and then when a new immutable
  * [ColorPalette] is provided, we can simply diff and update any values that need to be changed.
- * Because the internal values are provided by an @Model delegate class, components consuming the
+ * Because the internal values are provided by an State delegate class, components consuming the
  * specific color will be recomposed, while everything else will remain the same. This allows for
  * large performance improvements when the theme is being changed, especially if it is being
  * animated.
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt b/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
index 1c24800..954f11e 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
@@ -17,9 +17,12 @@
 package androidx.ui.material
 
 import androidx.compose.Composable
-import androidx.compose.Model
+import androidx.compose.Stable
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
 import androidx.compose.onDispose
 import androidx.compose.remember
+import androidx.compose.setValue
 import androidx.ui.core.Alignment
 import androidx.ui.core.DensityAmbient
 import androidx.ui.core.Layout
@@ -48,16 +51,18 @@
  * programmatically.
  * @param isDrawerGesturesEnabled whether or not drawer can be interacted with via gestures
  */
-@Model
+@Stable
 class ScaffoldState(
-    var drawerState: DrawerState = DrawerState.Closed,
-    var isDrawerGesturesEnabled: Boolean = true
+    drawerState: DrawerState = DrawerState.Closed,
+    isDrawerGesturesEnabled: Boolean = true
 ) {
 
+    var drawerState by mutableStateOf(drawerState)
+    var isDrawerGesturesEnabled by mutableStateOf(isDrawerGesturesEnabled)
     // TODO: add showSnackbar() method here
 
-    internal var fabConfiguration: FabConfiguration? = null
-    internal var bottomBarSize: IntPxSize? = null
+    internal var fabConfiguration: FabConfiguration? by mutableStateOf<FabConfiguration?>(null)
+    internal var bottomBarSize: IntPxSize? by mutableStateOf<IntPxSize?>(null)
 }
 
 object Scaffold {
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/AndroidComposeTestCaseRunnerTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/AndroidComposeTestCaseRunnerTest.kt
index f1c2749..e2c813a 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/AndroidComposeTestCaseRunnerTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/AndroidComposeTestCaseRunnerTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.ui.test
 
-import androidx.compose.Model
+import androidx.compose.mutableStateOf
 import androidx.compose.onPreCommit
 import androidx.compose.state
 import androidx.test.filters.SmallTest
@@ -27,11 +27,6 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-@Model
-private class TestModel {
-    var i = 0
-}
-
 @SmallTest
 @RunWith(JUnit4::class)
 class AndroidComposeTestCaseRunnerTest {
@@ -43,10 +38,10 @@
 
     @Test
     fun foreverRecomposing_viaModel_shouldFail() {
-        val model = TestModel()
+        val count = mutableStateOf(0)
         composeTestRule.forGivenContent {
-            Text("Hello ${model.i}")
-            model.i++
+            Text("Hello ${count.value}")
+            count.value++
         }.performTestWithEventsControl {
             assertFailsWith<AssertionError>(
                 "Changes are still pending after '10' frames.") {
@@ -132,11 +127,11 @@
 
     @Test
     fun recomposeTwice2() {
-        val model = TestModel()
+        val count = mutableStateOf(0)
         composeTestRule.forGivenContent {
-            Text("Hello ${model.i}")
-            if (model.i < 2) {
-                model.i++
+            Text("Hello ${count.value}")
+            if (count.value < 2) {
+                count.value++
             }
         }.performTestWithEventsControl {
             doFramesAssertAllHadChangesExceptLastOne(2)
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
index b21b853..7c084ca 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
@@ -20,8 +20,9 @@
 import android.widget.LinearLayout
 import android.widget.TextView
 import androidx.activity.ComponentActivity
-import androidx.compose.Model
+import androidx.compose.MutableState
 import androidx.compose.Recomposer
+import androidx.compose.mutableStateOf
 import androidx.test.espresso.Espresso
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
@@ -39,17 +40,13 @@
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 
-// TODO: Make this inner class once @Model gets fixed.
-@Model
-class CheckboxState(var value: ToggleableState = ToggleableState.Off) {
-    fun toggle() {
-        value =
-            if (value == ToggleableState.On) {
-                ToggleableState.Off
-            } else {
-                ToggleableState.On
-            }
-    }
+fun MutableState<ToggleableState>.toggle() {
+    value =
+        if (value == ToggleableState.On) {
+            ToggleableState.Off
+        } else {
+            ToggleableState.On
+        }
 }
 
 /**
@@ -85,8 +82,8 @@
 
         activity.runOnUiThread(object : Runnable { // Workaround for lambda bug in IR
             override fun run() {
-                val state1 = CheckboxState(value = ToggleableState.Off)
-                val state2 = CheckboxState(value = ToggleableState.On)
+                val state1 = mutableStateOf(value = ToggleableState.Off)
+                val state2 = mutableStateOf(value = ToggleableState.On)
 
                 val linearLayout = LinearLayout(activity)
                     .apply { orientation = LinearLayout.VERTICAL }
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/CoreText.kt b/ui/ui-text/src/main/java/androidx/ui/text/CoreText.kt
index 961c9a2..e16d170f 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/CoreText.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/CoreText.kt
@@ -242,7 +242,7 @@
     /**
      * The current selection range, used by selection.
      * This should be a state as every time we update the value during the selection we
-     * need to redraw it. @Model observation during onDraw callback will make it work.
+     * need to redraw it. state observation during onDraw callback will make it work.
      */
     var selectionRange by mutableStateOf<TextRange?>(null, StructurallyEqual)
     /** The last layout coordinates for the Text's layout, used by selection */
diff --git a/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt b/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
index c6f613c..1f89449 100644
--- a/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
+++ b/ui/ui-text/src/main/java/androidx/ui/text/CoreTextField.kt
@@ -251,7 +251,7 @@
     var inputSession = NO_SESSION
     /**
      * This should be a state as every time we update the value we need to redraw it.
-     * @Model observation during onDraw callback will make it work.
+     * state observation during onDraw callback will make it work.
      */
     var hasFocus by mutableStateOf(false)
     /** The last layout coordinates for the Text's layout, used by selection */